Hi there,
I am using WriteableBitmapEx as a base for a simple (wpf) image editor app, and it works wonderfully. However, recently I ran into a bit of a problem when trying to use ToByteArray() /FromByteArray() as a means to modify Brightness and Contrast of my images. Below is the code snippet with custom extension methods I wrote.
The problem that I have is that my Brightness and Contrast are just fine when I go into positive range. When the value is being changed towards lower end though ( negatives brightness ) the areas in my image that are supposed to turn black actually turn transparent! Is there a reason for this ? I also noticed that if I remove getting and setting up the alpha channel nothing changes at all. One of the issues of course is that the images I am trying to edit are greyscale, so technically I don't even need all three RGB values, but WriteableBitmapEx enforces Pbgra32 so I convert my images into it for editing. (Which is no big deal.) Btw, ToByteArray() /FromByteArray() works really really fast - I can actually drag the slider and see the change 'in real time', unlike when I use any other option. In comparison Get/SetPixel is virtually unusable here as it is extremely slow. But the pesky transparency issue I can do nothing about... Can somebody please help ?
I am using WriteableBitmapEx as a base for a simple (wpf) image editor app, and it works wonderfully. However, recently I ran into a bit of a problem when trying to use ToByteArray() /FromByteArray() as a means to modify Brightness and Contrast of my images. Below is the code snippet with custom extension methods I wrote.
The problem that I have is that my Brightness and Contrast are just fine when I go into positive range. When the value is being changed towards lower end though ( negatives brightness ) the areas in my image that are supposed to turn black actually turn transparent! Is there a reason for this ? I also noticed that if I remove getting and setting up the alpha channel nothing changes at all. One of the issues of course is that the images I am trying to edit are greyscale, so technically I don't even need all three RGB values, but WriteableBitmapEx enforces Pbgra32 so I convert my images into it for editing. (Which is no big deal.) Btw, ToByteArray() /FromByteArray() works really really fast - I can actually drag the slider and see the change 'in real time', unlike when I use any other option. In comparison Get/SetPixel is virtually unusable here as it is extremely slow. But the pesky transparency issue I can do nothing about... Can somebody please help ?
public unsafe static void SetBrightnessInContext(this WriteableBitmap bmp, int brightness)
{
if (brightness < -255) brightness = -255;
if (brightness > 255) brightness = 255;
byte[] pixeli = bmp.ToByteArray();
int l = pixeli.Length;
for (int i = 0; i < l; i++)
{
int pixel = pixeli[i];
int B = (int)(pixel & 0xFF); pixel >>= 8;
int G = (int)(pixel & 0xFF); pixel >>= 8;
int R = (int)(pixel & 0xFF); pixel >>= 8;
int A = (int)(pixel);
if (A == 0)
{
A = 1;
}
B += brightness;
R += brightness;
G += brightness;
if (R > 255) R = 255; if (G > 255) G = 255; if (B > 255) B = 255;
if (R < 0) R = 1; if (G < 0) G = 1; if (B < 0) B = 1;
byte r = (byte)(R);
byte g = (byte)(G);
byte b = (byte)(B);
byte a = (byte)(A);
pixeli[i] = (byte)((a << 24) | (r << 16) | (g << 8) | b); //(byte)(B | (G << 8) | (R << 16) | (A << 24));
}
bmp = bmp.FromByteArray(pixeli);
}
public unsafe static void SetContrastInContext(this WriteableBitmap bmp, double contrast)
{
if (contrast < -100) contrast = -100;
if (contrast > 100) contrast = 100;
contrast = (100.0 + contrast) / 100.0;
contrast *= contrast;
byte[] pixeli = bmp.ToByteArray();
int l = pixeli.Length;
for (int i = 0; i < l; i++)
{
int pixel = pixeli[i];
int B = (int)(pixel & 0xFF); pixel >>= 8;
int G = (int)(pixel & 0xFF); pixel >>= 8;
int R = (int)(pixel & 0xFF); pixel >>= 8;
int A = (int)(pixel);
R = (int)Math.Max(0, Math.Min(255, (((R - 128) * contrast) + 128)));
G = (int)Math.Max(0, Math.Min(255, (((G - 128) * contrast) + 128)));
B = (int)Math.Max(0, Math.Min(255, (((B - 128) * contrast) + 128)));
if (R > 255) R = 255; if (G > 255) G = 255; if (B > 255) B = 255;
if (R < 0) R = 1; if (G < 0) G = 1; if (B < 0) B = 1;
byte r = (byte)R;
byte g = (byte)G;
byte b = (byte)B;
byte a = (byte)A;
pixeli[i] = (byte)((a << 24) | (r << 16) | (g << 8) | b); //(byte)(B | (G << 8) | (R << 16) | (A << 24));
}
bmp = bmp.FromByteArray(pixeli);
}