How to change background color of sprites to transparent by changing alpha after loading it to a SDL_Surface. Are there any functions in SDL which use a floodfill kind of algorithm and change all pixel with a given color to transparent on the outside. I don't want it to happen inside the border of the sprite if the same color is used.
Sample Image:
I would like to make the background blue here transparent before I blit it on the window surface using SDL_BlitSurface.
Only a color key (SDL_SetColorKey()) or a full alpha channel are going to help you here.
Note, that you can provide an alpha channel in your source graphics if you use a format such as PNG. If you only sometimes need/want an alpha, then provide the alpha channel in your source graphics and use SDL_SetSurfaceBlendMode() with SDL_BLENDMODE_NONE to blend without the alpha and SDL_BLENDMODE_BLEND to blend with it.
Both SDL_Surface and SDL_Texture support SDL_BlendMode.
Even if SDL provided another method, such as the fill you mentioned. You wouldn't want to use that. It is more difficult, expensive, and unnecessary overhead. You should stick with best practices here.
You may want to look into SDL_Texture and SDL_Renderer and switch to using a "texture atlas" instead of individual surfaces/textures for each image to maximize performance.
Related
I have a directX11 texture which is of ARGB format. (different pixels has different alpha value, like the one below)
I need to render that texture on a transparent Window which means the desktop should appear behind the texture.
I am using SetLayeredWindowAttributes which could make the window transparent but it's boolean, i.e. a pixel appears either fully transparent or doesn't appear. I need to achieve per-pixel transparency level - where darkness is defined by the alpha value of the pixel (Something like AlphaBlend). How to achieve it?
Use UpdateLayeredWindow instead. Select a 32-bit ARGB bitmap into the source HDC.
A more fancy solution is WS_EX_NOREDIRECTIONBITMAP and ICompositorDesktopInterop but this is probably overkill in this case unless you need to do updates often. MSDN magazine did have a few articles about this. DirectComposition is intended to interop with Direct2D etc. where as UpdateLayeredWindow is much older and predates the DWM and any kind of visual tree rendering.
I am trying to paint rectangles in locations which face detection algorithm locate faces. I want to use alpha transparency in order to draw my rectangles. I have found in opencv documentation the following in here: Note The functions do not support alpha-transparency when the target image is 4-channel. In this case, the color[3] is simply copied to the repainted pixels. Thus, if you want to paint semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main image.
How is it possible to blend main image with buffer image? And what exactly means with buffer image?
You can use the OpenCV addWeighted function to blend your image.
Refer to the documentation of the function.
You can provide the function with the amount of transparency you want to have.
Here is an tutorial to do so.
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 am trying to display a bitmap using opengl but I don't want the black portion of the image to be displayed. I can do this in DirectX but not in opengl. In other words - I have images of plants with a black background and I want the plants to be drawn so they look realistic (without a black border).
You can do this using alpha-testing:
Add an alpha channel to your image before uploading it to a texture, 0.0 on black pixels and 1.0 everywhere else.
Enable alpha-testing with glEnable( GL_ALPHA_TEST )
glAlphaFunc( GL_LESS, 0.1f )
Render textured quad as usual. OpenGL will skip the zero-alpha texels thanks to the alpha-test.
There are a couple of ways you can do this.
One is to use an image editing program like Photoshop or GIMP to add an alpha channel to your image and then set the black portions of the image to a max alpha value. The upside to this is it allows you to decide which portions of the image you want to be transparent, since a fully programmatic approach can sometimes hide things you want to be seen.
Another method is to loop through every pixel in your bitmap and set the alpha based on some defined threshold (i.e. if you want true black, check to see if each color channel is at 255). The downside to this is it will occasionally cause some of your lines to disappear.
Also, you will need to make sure that you have actually enabled the alpha channel and test, as stated in the answer above. Make sure to double check the order of your calls as well, as this can cause a lot of issues when you're trying to use transparency.
That's about as much as I can suggest since you haven't posted the code itself, but hopefully it should be enough to at least get you on the way to a solution.
I've run into issues preserving the alpha channels of surfaces being copied/clip blitted (blitting sections of a surface onto a smaller surface, they're spritesheets). I've tried various solutions, but the end result is that any surface that's supposed to have transparency ends up becoming fully opaque (alpha mask becomes white).
So my question is, how does one copy one RGBA SDL_Surface to another new surface (also RGBA), including the alpha channel? And if it's any different, how does one copy a section of an RGBA surface, to a new RGBA surface (the same size of the clipped portion of the source surface), ala tilesheet blitting.
It seems that SDL_BlitSurface blends the alpha channels, so when for example, I want to copy a tile from my tilesheet surface to a new surface (which is of course, blank, I'm assuming SDL fills surfaces with black or white by default), it ends up losing it's alpha mask, so that when that tile is finally blitted to the screen, it doesn't blend with whatever is on the screen.
SDL_DisplayFormatAlpha works great to copy surfaces with an alpha mask, but it doesn't take clip parameters, it's only intended to copy the entire surface, not a portion of it, hence my problem.
If anyone is still wondering after all these years:
Before bliting the surface, you need to make sure that the blending mode of the source (which is an SDL_Surface) is set to SDL_BLENDMODE_NONE as described in the documentation: SDL_SetSurfaceBlendMode(). Is should look something simple like this:
SDL_SetSurfaceBlendMode(source, SDL_BLENDMODE_BLEND);
SDL_BlitSurface(source, sourceRect, destination, destinationRect);
I had this problem before and have not come to an official answer yet.
However, I think the only way to do it will be to write your own copy function.
http://www.libsdl.org/docs/html/sdlpixelformat.html
This page will help you understand how SDL_Surface stores color information. Note that there is a huge difference between colors above and below 8 bits.