I have a blur effect on an image which changes the value with a slider.
just simply .blur(radius: blurAmmount)
When i use a blur radius of around 20, the edges become trasparent which i would like to avoid? Is there a method to apply a gausian blur (or any other blur effects) for example without creating transparent edges?
.blur modifier also has opaque parameter that is defaulted to false. You can set it to true like:
.blur(radius: 10, opaque: true)
Related
I have some rounded rectangle geometry.
ID2D1RoundedRectangleGeometry *geo; (1)
First I draw it
target->FillGeometry(geo, brush); (2)
Then I apply clipping mask using ID2D1Layer with the same geometry:
target->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), geo), nullptr); (3)
And then, with layer I make some draw over it:
target->FillGeometry(mask, anotherBrush); (4)
... another draw calls
The result:
As you can see there is a problem with edges, seems like some part of initial draw (1) is not covered by mask, although has the same geometry.
Can it be solved without resizing initial draw area or the layer area?
Specifying antialias mode at (3), changes the result a bit, but still unsatisfying:
target->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), geo, D2D1_ANTIALIAS_MODE_ALIASED), nullptr); (3)
I'm trying to use QPainter::drawEllipse to draw circles. I want to be able to:
set the width of the stroke of the circle (QPen::width)
choose the shape of the pixels that are at the center of the circle (1x1, 1x2, 2x1 or 2x2)
optionally make the circle filled instead of stroked
ensure that the circle has the correct radius (even when the stroke width is greater than 1)
These goals are surprisingly difficult to achieve. This is an example of what I want to render (drawn by hand):
The image is 32x32 (scaled up to 512x512). The red center point is at (15, 15). The center is 1x2 so there's an extra red pixel below the center pixel. The stroke has a width of 2 pixels. If the stroke was made wider, pixels would be added to the inside of the circle. The bounding box of the circle is the same regardless of stroke width. The radius is 8 pixels. Each of the blue lines is 8 pixels long. Just to be clear, the red and blue pixels are just there for describing the circle. They are not part of my desired output.
What my problem really boils down to is rendering an ellipse that fits perfectly inside a rectangle. I can calculate the rectangle using the center point, the radius, and the center shape. That part is easy. Simply calling drawEllipse with this rectangle doesn't work. I think I have to adjust this rectangle somehow before calling drawEllipse but I'm not too sure how to adjust it. I've tried fiddling around with it and I found some solutions that work for some pen widths but not others.
Does the pen cap matter? I've been using RoundCap. Should I be using a different cap?
I'm almost at the point where I'm considering doing the pixel manipulation myself. I'm rendering onto a QImage and using the Source composite operation so my code might be slightly faster than drawEllipse. memset is about 10x faster than QImage::fill so writing faster code probably won't be too hard! I'd rather not have to do that though.
I stumbled upon a section in the docs that talks about how QRects are rendered. It describes the relationship between the rendered pixels and the logical rectangle. The rendered rectangle is bigger than the logical rectangle. All I have to do is make the logical rectangle smaller to compensate.
QRect adjustStrokedRect(const QRect rect, const int thickness) {
return QRect{
rect.left() + thickness / 2,
rect.top() + thickness / 2,
rect.width() - thickness,
rect.height() - thickness
};
}
Ok, so now I can get stroked rectangles to render in the right place. An ellipse is described by a QRect so what if I just apply this transformation to that rectangle?
Nope.
It sort of works if the thickness is 1, 2, 4, 6 but not 3, 5, 7. The circle is one pixel too small when the thickness is 3, 5, 7. So I tried adding 1 to the rectangle size if thickness % 2 == 1 && thickness != 1 but then an asymmetric circle is rendered from a square. For some combinations of position and size, a wonky asymmetric circle is rendered even when the size is square.
Here's a weird image that you can easily reproduce:
Produce it with this code:
QImage image{32, 32, QImage::Format_ARGB32_Premultiplied};
QPainter painter{&image};
QPen pen{Qt::NoBrush, 3.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin};
pen.setColor(QColor{0, 255, 0, 255});
painter.setPen(pen);
painter.drawEllipse(8, 8, 17, 17);
image.save("weird.png");
I simply don't understand how that's even possible. To me, it seems like drawEllipse is rendering an ellipse that just roughly fits within the rectangle. I haven't been able to find the relationship between the rectangle and the ellipse anywhere in the docs. Perhaps this is because it's a very loose relationship.
I have no trouble getting QPainter::drawEllipse to draw circles with a stroke width of 1 so for now I just won't allow thick circles in my application. If I can’t render it perfectly, I won’t render it at all. I'm not marking this answer as accepted though as I would still like this to work.
I probably am too late for this, but still, for future reference:
Unfortunately, Qt plots ellipses using Bezier curves (as of now, which might just change soon) , which is a pretty good approximation of an ellipse, but isn't perfect. Plotting a pixel-perfect ellipse would require a manual implementation at the pixel level.
Try setting this QPainter flag to true:
painter->setRenderHint(QPainter::Antialiasing, true);
Did the trick for me!
I have a QTableWidget. I want to have alternating background colors for the rows, but I can't use QTableWidget::setAlternatingRowColors because I need one color for two rows and the other one for the next two and so on (see the below image).
Thus, when I add a QTableWidgetItem, I set the according background color manually by QTableWidgetItem::setBackground().
But I don't get a "flat" or "plain" background by this, but a gradient and rounded corners:
I would like to have the background color all over the cells, without further "decoration". How can I get rid of this?
When you select a single color as the background (QBrush constructed from a QColor), the style engine tries to render a styled background, which in your case draws this gradient with border.
You can trick the style engine by using a QBrush constructed from a QImage, so the render engine draws exactly that image and nothing more. In your case, use an image with a single pixel, namely the color you want as the background. For this, construct a 1x1-sized QImage and set the color of the pixel using fill, then use that image as a brush:
// Create the image (using the default image format)
QImage img(QSize(1, 1), QImage::Format_ARGB32_Premultiplied);
// Set the color, here light gray:
img.fill(QColor(224, 224, 224));
// Apply the image as the background for the item:
item->setBackground(QBrush(img));
I am currently doing the following for putting a circular mask on my image. As a result only circular region of my image is displayed.This works fine however the image tends to have jagged edges (border). Any suggestion on how I could do this.
From the documentation of QPixmap you can learn:
The hasAlpha(), setMask() and mask() functions are legacy and should not be used. They are potentially very slow.
Apart from being slow, they operate on a binary mask (QBitmap) which does not support anti-aliasing, each pixel is either fully opaque or fully transparent. This results in jagged edges.
The solution is to manipulate the alpha channel of the pixmap directly. However, you cannot use drawing operations on a pixmap. Instead, you need to draw on the QImage before converting it via QPixmap::fromImage().
With this method, the alpha channel you manipulate has 8 bits (instead of 1) which allows antialiasing. At the edges you will find a smooth transition between fully opaque and fully transparent.
So to draw the alpha in the original QImage:
Make sure that it actually has an alpha channel, e.g. by calling img.convertToFormat(QImage::Format_ARGB32);
Initialize your QPainter on img as paint device
Set the DestinationIn composition mode on the painter; see http://qt-project.org/doc/qt-4.8/qpainter.html#CompositionMode-enum
Perform the drawEllipse operation with a white brush of a certain alpha.
I think the easiest way is:
oImage.convertToFormat(QImage::Format_ARGB32);
QImage oCircleProfileImage (oImage.width(), oImage.height(), QImage::Format_ARGB32);
oCircleProfileImage.fill(Qt::transparent);
QBrush oImageBrush(oImage);
QPainter oPainter(&oCircleProfileImage);
oPainter.setBrush(oImageBrush);
oPainter.setPen(Qt::NoPen);
oPainter.setRenderHint(QPainter::Antialiasing);
oPainter.drawEllipse(0, 0, oImage.width(), oImage.height());
Where oImage is your image you want to be in a circle.
I'm new to programming with c++ and direct3d. I try to draw textures(LPDIRECT3DTEXTURE9) on the screen with a sprite(LPD3DXSPRITE). But when I draw a texture it seems to enlarge it, a 100x100 px texture is not drawn from coordinates (100, 100) to (200, 200) but from (100, 100) to (227, 227), I tested that by drawing 1x1 px blocks at those coordinates. I can't figure out why this is the case... Is the creation of the LPDIRECT3DDEVICE9 of any influence on it or could it be something completely different?
This seems to be a scaling issue. When you first call CreateTextureFromFile(), the function causes the texture to be scaled to a power of 2 rule (512, 256 for example). To fix this, simply call the setScale function to 1,1 and this should fix your problem :)