Setting the background of my image in WPF - wpf

Im having a grid in whre the user can specify an image to be shown, and its alignment. If the user chooses a small image and aligns it bottom -right, i want to provide the user with an option to assign a background color to fill in the rest, eg. pink/black/white. When the user now chooeses a small image the background is always white and i cant seem to get it right at runtime:
byte r = (byte)Convert.ToInt32(backcolorR);
byte g = (byte)Convert.ToInt32(backcolorG);
byte b = (byte)Convert.ToInt32(backcolorB);
((Grid)container).Background = new SolidColorBrush(Color.FromArgb(0, r, g, b));
This isnt working, its like, the image fille the entire grid and i should set the background color on the image instead... is this possible?

The first argument of Color.FromArgb represents the Alpha blending value. 0 meaning fully transparent, 255 meaning totally not transparent (fully opaque). You're requesting a fully transparent color which means you don't see any color, just the background. I guess the color of the element your grid is on is white. Use this code to fix your problem:
Color.FromArgb(255, r, g, b)
// or
Color.FromArgb(r, g, b)

Related

Blending text, rendered by FreeType in color and alpha

I am using FreeType to render some texts.
The surface where I want to draw the text is a bitmap image with format ARGB, pre-multiplied alpha.
The needed color of the text is also ARGB.
The rendered FT_Bitmap has format FT_PIXEL_MODE_LCD - it is as the text is rendered with white color on black background, with sub-pixel antialiasing.
So, for every pixel I have 3 numbers:
Da, Dr, Dg, Db - destination pixel ARGB (the background image).
Fr, Fg, Fb - FreeType rendered pixel (FT_Bitmap rendered with FT_RENDER_MODE_LCD)
Ca, Cr, Cg, Cb - The color of the text I want to use.
So, the question: How to properly combine these 3 numbers in order to get the result bitmap pixel.
The theoretical answers are OK and even better than code samples.
Interpet the FreeType data not as actual RGB colors (these 'raw' values are to draw text in black) but as intensities of the destination text color.
So the full intensity of each F color component is F*C/255. However, since your C also includes an alpha component, the intensity is scaled by it:
s' = F*C*A/(255 * 255)
assuming, of course, that F, C, and A are inside the usual range of 0..255. A is a fraction A/255, and the second division is to bring F*C back into the target range. s' is now the derived source color.
On to plotting it. Per color component, the new color gets add to D, and D in turn gets dimished by the source's alpha 255-A (scaled).
That leads to the full sum
D' = D*(255-A)/255 + F*C*A/(255 * 255)
equal to (moving one value to the right)
D' = (D*(255-A) + F*C*A/255)/255
for each separate channel r,g,b of D, F, C and A. The last one, alpha, also needs a separate calculation for each channel because your FreeType output data returns this format.
If the calculation is too slow, you could compare the visual result with not-LCD-optimized grayscale output from FreeType. I suspect that especially on 'busy' (not entirely monochrome) backgrounds the extra calculations are simply not worth it.
The numerical advantage of a pure grayscale input is that you only have to calculate A and 1-A once for each triplet of RGB colors.
The "background" also has an alpha channel but to draw text "on" it you can regard this as 'unused'. Drawing a transparent item onto another transparent item does not, in general, change its intrinsic transparency.
After some discovery, I found the right answer. It is disappointing.
It is impossible to draw subpixel rendered graphics (including fonts) on a transparent image with RGBA format.
In order to properly render such graphics, a format that supports separate alpha channels for every color is mandatory.
For example 48 bit per pixes: RrGgBg where r, g and b are the alpha channels for the red, green and blue collor channels respectively.

ImageMagick advanced transparency control

I'm trying to put overlay (watermark) on base image. Assuming it looks like this:
opaque rectangle with "fully transparent" text on it. I.e. all pixels of text is transparent, as well as background under it.
1 way:
I do opacity 60% in Photoshop:
And just compose it in code:
MagickWand* overlay = NewMagickWand();
MagickReadImage(overlay, overlaypath);
MagickCompositeImage(wand, overlay, OverCompositeOp, 100, 100);
//all open/destroy code is omitted
And result is rectangle is semi-transparent while text is fully transparent:
So far so good, but I also wanted to regulate overlay opacity via application config, so I tried second way:
2 way:
100% in Photoshop (as on very first image in this post) and trying to set transparency via MagickWand:
MagickReadImage(overlay, overlaypath);
MagickSetImageOpacity(overlay, 0.6);
MagickCompositeImage(wand, overlay, OverCompositeOp, 100, 100);
Result is totally blank rectangle, semi-transparent though
It looks like MagickSetImageOpacity set up every pixel alpha channel to the same 0.6 value regardless of its current value. What I need is currentAlpha -= givenAlpha for every pixel of overlay wand. Is this possible without iterate every wand pixel by hand?
The correct way to achieve the currentAlpha -= givenAlpha would be to invoke a PixelIterator, and iterator through each pixel, and apply the givenAlpha with PixelSetAlpha. But for you needs, you may be able to apply the same effects with MagickColorizeImage.
PixelWand *pColorize = NewPixelWand();
PixelWand *pGivenAlpha = NewPixelWand();
double userOpacity = 0.6;
// May need to be adjusted to "white" or "black" depending on your mask
PixelSetColor(pColorize, "transparent");
PixelSetAlpha(pGivenAlpha, userOpacity);
MagickWand *overlay = NewMagickWand();
MagickReadImage(overlay, overlaypath);
MagickColorizeImage(overlay, pColorize, pGivenAlpha); // Apply opacity filter
MagickCompositeImage(wand, overlay, OverCompositeOp, 100, 100);

What's the RGB Color For the Windows COLOR_WINDOW or COLOR_BACKGROUND?

In the Windows Api and GDI, you can use the default window background color for drawing buttons and stuff (that slight greyish color on Win98 , WinXP + Classic Theme etc. ).
What is the rgb value for that?
So I can emulate the exact color in Allegro using al_map_rgb( r, g, b) ?
It depends on the users settings.
You should use GetSysColor function to retrieve the DWORD value and then use GetRValue, GetGValue, and GetBValue to retrieve red, green and blue component values.
Although Bobrovsky's answer (use GetSysColor) is likely the right solution to the actual problem, if you want to know the default warm gray color regardless of the user's settings, it's R=212, G=208, B=200.
(The simple way to determine this was take a screenshot of a window, paste it into Paint, use the color picker tool on a bit of the default gray, and then open the "edit colors" dialog box to view the RGB values in it.)

calculate selection brush color in WPF

I have noticed when setting the selection of a text box in wpf to red, and using a color picker to verify the color, the color faded to #FF9999.
I have a specific color my client requires for the selection brush. Is there a way to calculate what color i should set the SelectionBrush to so when the text is selected, the exact color is displayed?
Currently I need to have the selection brush as #6599D1, but once set, the color is #C1D6ED.
How can I calculate the starting color so the end color is what I need?
Following up on the answer by H.B.
I've calculated opacity with the following formula in the past
Red = OriginalRed * Opacity + (1-Opacity) * BackgroundRed
which inverts to
(Red - (1-Opacity) * BackgroundRed) / Opacity = OriginalRed
The TextBox has default Background set to White and SelectionOpacity set to 0.4.
As H.B. explained, you can't achieve your color with these default settings since the Red value will come out as -130. This leaves you with 3 options, Change Background, change SelectionOpacity or don't do it :)
Changing the TextBox Background probably isn't something you wanna do so that leaves option 2, change SelectionOpacity
We don't want Red to go below 0 so
(101 - (1-Opacity) * 255) = 0
which gives
1 - (101/255) = Opacity
This results in 0,604 so with this SelectionOpacity value you can calculate that the SelectionBrush needs to be set to #0056B3 to become #6599D1 once the Opacity has been applied.
Here's how the TextBox look with these values
<TextBox SelectionBrush="#0056B3"
SelectionOpacity="0.604" />
Good question but i think this is impossible. If there is some overlay inside the ControlTemplate you cannot formulate a function which calculates a darker colour which then will end up as the intended colour.
e.g. when you input red which is: 255,0,0 you get 255,153,153, now the function that would need to be applied to your initial colour would need to darken the Red, this of course could only be done in the red channel as green and blue are already zero. The problem is not the red channel however (which ends up as 255 and hence is not affected), so any changes to that will only serve to desaturate the colour even more instead of darkening it.
Edit: To make this a bit more mathmatical, the function that is applied by the transparency of the selection is:
f(x) = 0.4x + 153
If you apply this to all the channels of your colour you will see that this is indeed the case. Now how do we get the values we want? Quite simple, we invert the function, which is this:
f^(-1)(x) = -2.5(153.0 - x)
Great! Now lets apply that to your colour:
R: -130.0
G: 0
B: 140
Hmm, not so great after all i suppose.
This negative value is exactly why this is not always possible, every colour which has components below 153 is not reversible.

Making a color completely transparent in OpenCV

I have a basic png file with two colors in it, green and magenta. What I'm looking to do is to take all the magenta pixels and make them transparent so that I can merge the image into another image.
An example would be if I have an image file of a 2D character on a magenta background. I would remove all the magenta in the background so that it's transparent. From there I would just take the image of the character and add it as a layer in another image so it looks like the character has been placed in an environment.
Thanks in advance.
That's the code i would use,
First, load your image :
IplImage *myImage;
myImage = cvLoadImage("/path/of/your/image.jpg");
Then use a mask like this to select the color, you should refer to the documentation. In the following, I want to select a blue (don't forget that in OpenCV images are in BGR format, therefore 125,0,0 is a blue (it corresponds to the lower bound) and 255,127,127 is blue with a certain tolerance and is the upper bound.
I chose lower and upper bound with a tolerance to take all the blue of your image, but you can select whatever you want...
cvInRangeS(image,
cvScalar(125.0, 0.0, 0.0),
cvScalar(255.0, 127.0, 127.0),
mask
);
Now we have selected the mask, let's inverse it (as we don't want to keep the mask, but to remove it)
cvNot(mask, mask);
And then copy your image with the mask,
IplImage *myImageWithTransparency; //You may need to initialize it before
cvCopy(myImage,myImageWithTransparency,mask);
Hope it could help,
Please refer to the OpenCVDocumentation for further information
Here it is
Julien,

Resources