Extract RGB information from image into an array - c#

I must save a bitmap file, and then access the rgb of each pixel and save the decimal code of each color of pixel (meaning red, green and blue) in a separate matrix (array).
For hidding textfile in bmp lmage l need to save each rgb code in seperate matrix...lm looking for effiecient way,this is my code
This code will be run,but l cant show the result of each matrix in text of lable.how can I see the output of each matrix?
Bitmap bmp1 = new Bitmap(#"D:a.jpg");
pictureBox1.Image = bmp1;
Color col = new Color();
int w = Int32.Parse(bmp1.Width.ToString());
int h = Int32.Parse(bmp1.Height.ToString());
int[,] redstr = new int[w,h];
int[,] greenstr = new int[w, h];
int[,] bluestr = new int[w, h];
int red = 0, green = 0, blue = 0;
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
col = bmp1.GetPixel(i, j);
red = col.R;
green = col.G;
blue = col.B;
redstr[i, j] = red;
greenstr[i, j] = green;
bluestr[i, j] = blue;
}
}

From the following page ... https://msdn.microsoft.com/en-us/library/system.drawing.bitmap.getpixel.aspx
You can use something like this to access each pixel of an image ...
private void GetPixel_Example(PaintEventArgs e)
{
// Create a Bitmap object from an image file.
Bitmap myBitmap = new Bitmap("YOURFILENAME.jpg");
// Get the color of a pixel within myBitmap.
Color pixelColor = myBitmap.GetPixel(50, 50);
}
then you can check pixelColour for your RGB components.
Evidently you will need to create a 2D array (matrix) with the same dimensions as your image. And if you need to store the separate RGB components, then you will need a 3D array.

Related

How to convert gray image into colormap

enter image description here
i have a color feet image, it transform to grayscale, and then to colormap (jet)
i did it in emgucv, but the color doesnt look so diferent, i need that the result image like the second (only 4-6 color, red, orange*, yellow, green, blue, purple*)
it is possible?
i already try on emgucv and read something gdi+, but i dont understand, i just begin to program
i try this but the color are the same, just more pixel, no gradient
int divideWith = 48;
byte[] table = new byte[256];
for (int i = 0; i < 256; i++)
{
table[i] = (byte)(divideWith * (i / divideWith));
}
Mat mat = ConvertBitmapToMat(rgb);
//_Stopwatch.Reset();
int rows = mat.Rows;
int cols = mat.Cols;
byte[,,] data = mat.ToImage<Bgr, byte>().Data;
byte[,,] resData = new byte[rows, cols, 3];
Parallel.For(0, rows, i =>
{
for (int j = 0; j < cols; j++)
{
resData[i, j, 0] = table[data[i, j, 0]];
resData[i, j, 1] = table[data[i, j, 1]];
resData[i, j, 2] = table[data[i, j, 2]];
}
});
Image<Bgr, byte> resImg = new Image<Bgr, byte>(resData);
Bitmap im = resImg.ToBitmap();
pictureBox2.Image = im;

Convert ARGB to PARGB

I've been looking for a fast alternative method of SetPixel() and I have found this link : C# - Faster Alternatives to SetPixel and GetPixel for Bitmaps for Windows Forms App
So my problem is that I've an image and I want to create a copy as a DirectBitmap object but first I need to convert ARGB to PARGB so I used this code:
public static Color PremultiplyAlpha(Color pixel)
{
return Color.FromArgb(
pixel.A,
PremultiplyAlpha_Component(pixel.R, pixel.A),
PremultiplyAlpha_Component(pixel.G, pixel.A),
PremultiplyAlpha_Component(pixel.B, pixel.A));
}
private static byte PremultiplyAlpha_Component(byte source, byte alpha)
{
return (byte)((float)source * (float)alpha / (float)byte.MaxValue + 0.5f);
}
and Here's my copy code:
DirectBitmap DBMP = new DirectBitmap(img.Width, img.Height);
MyImage myImg = new MyImage(img as Bitmap);
for (int i = 0; i < img.Width; i++)
{
for (int j = 0; j < img.Height; j++)
{
Color PARGB = NativeWin32.PremultiplyAlpha(Color.FromArgb(myImg.RGB[i, j].Alpha,
myImg.RGB[i, j].R, myImg.RGB[i, j].G, myImg.RGB[i, j].B));
byte[] bitMapData = new byte[4];
bitMapData[3] = (byte)PARGB.A;
bitMapData[2] = (byte)PARGB.R;
bitMapData[1] = (byte)PARGB.G;
bitMapData[0] = (byte)PARGB.B;
DBMP.Bits[(i * img.Height) + j] = BitConverter.ToInt32(bitMapData, 0);
}
}
MyImage : a class containing a Bitmap object along with an array of struct RGB storing the colors of each pixel
However, this code gives me a messed up image. what am I doing wrong?
Bitmap data is organized horizontal line after horizontal line. Therefore, your last line should be:
DBMP.Bits[j * img.Width + i] = BitConverter.ToInt32(bitMapData, 0);

Why is SetPixel not working correctly with ColorDialog?

I'm trying to change an image color by using Bitmap.SetPixel method. And I have a problem when using it like this:
Bitmap bmp = new Bitmap(Project1.Properties.Resources.gray_square_button);
int Width = bmp.Width;
int Height = bmp.Height;
Bitmap Nbmp = new Bitmap(bmp);
ColorDialog ColorDialog = new ColorDialog();
ColorDialog.AllowFullOpen = true;
DialogResult result = ColorDialog.ShowDialog();
if (result == DialogResult.OK)
{
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
System.Drawing.Color BackColor = ColorDialog.Color;
System.Drawing.Color p = bmp.GetPixel(x, y);
int a = BackColor.A;
int r = BackColor.R;
int g = BackColor.G;
int b = BackColor.B;
Nbmp.SetPixel(x, y, System.Drawing.Color.FromArgb(a, r, g, b));
}
}
PictureBox1.Image = Nbmp;
}
It will only draw a square with the color that I choose like in this image:
But if I use it like this, using a manual color and the original image color references (p insted of BackColor which is the color defined by the ColorDialog):
if (result == DialogResult.OK)
{
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
System.Drawing.Color BackColor = ColorDialog.Color;
System.Drawing.Color p = bmp.GetPixel(x, y);
int a = p.A;
int r = p.R;
int g = p.G;
int b = p.B;
Nbmp.SetPixel(x, y, System.Drawing.Color.FromArgb(a, r, 0, 0));
}
}
PictureBox1.Image = Nbmp;
}
The color is applied correctly and the image is displayed correctly as well:
What i've tried is changing only 1 value of the RGB color. But then if you choose a color the color will not be the one you selected but a different one based on the one that is modified by the Color of the Color Dialog.
int a = p.A;
int r = BackColor.R;
int g = p.G;
int b = p.B;
Why are the ColorDialog RGB values not allowing the image to be displayed correctly but only a colored square?
This is the original image:
You're replacing the colour of a "shaded" image with a flat selected colour from a ColorDialog. So basically, you're replacing every pixel, regardless of ARGB, with a single ARGB from the dialog, thus completely overwriting any existing image information. You may as well just draw the image from scratch based on the old image's dimensions, without concern for the original image since it's being completely rewritten.
It sounds like what you are probably intending to do is blend the 2 colours together (the original image + the new colour). There are literally hundreds of ways to do this. One that comes to mind is to create an overlay with 50% transparency and apply it over the original image. You could also set the ARGB to an average:
int a = (BackColor.A + p.A) / 2;
int r = (BackColor.R + p.R) / 2;
int g = (BackColor.G + p.G) / 2;
int b = (BackColor.B + p.B) / 2;
This will give you a feel for how to consider the original colours while changing them versus flat out replacing them.

How to save an image from RGB pixels array?

Recently I learned how to save an image as bytes (RGB values in a text file), and now I'd like to know how to create a perfectly valid image from array of RGB values.
You can use the approach mentioned by #dasblinkenlight:
int width = 1; // read from file
int height = 1; // read from file
var bitmap = new Bitmap(width, height, PixelFormat.Canonical);
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
int red = 0; // read from array
int green = 0; // read from array
int blue = 0; // read from array
bitmap.SetPixel(x, y, Color.FromArgb(0, red, green, blue));
}

Image Processing in C# - A smart solution?

I have an image with letters in it, the letters are in two colors black and blue, I want to read the blue colored letters from the image.
Can anyone suggest me a method to do this in C#. Iam studying GDI+,but still didn't get any logic to develop this program..
I tried OCRing it, but the issue with common OCRs is that they dont recognize the color difference.
I only want to read the Blue characters....
Any guidance is highly appreciated.
Try this one ;) But that's unsafe code.
void RedAndBlue()
{
OpenFileDialog ofd;
int imageHeight, imageWidth;
if (ofd.ShowDialog() == DialogResult.OK)
{
Image tmp = Image.FromFile(ofd.FileName);
imageHeight = tmp.Height;
imageWidth = tmp.Width;
}
else
{
// error
}
int[,] bluePixelArray = new int[imageWidth, imageHeight];
int[,] redPixelArray = new int[imageWidth, imageHeight];
Rectangle rect = new Rectangle(0, 0, tmp.Width, tmp.Height);
Bitmap temp = new Bitmap(tmp);
BitmapData bmpData = temp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int remain = bmpData.Stride - bmpData.Width * 3;
unsafe
{
byte* ptr = (byte*)bmpData.Scan0;
for (int j = 0; j < bmpData.Height; j++)
{
for (int i = 0; i < bmpData.Width; i++)
{
bluePixelArray[i, j] = ptr[0];
redPixelArray[i, j] = ptr[2];
ptr += 3;
}
ptr += remain;
}
}
temp.UnlockBits(bmpData);
temp.Dispose();
}
Modify the color of the image to gray scaled then use OCR
public Bitmap MakeGrayscale(Bitmap original)
{
//make an empty bitmap the same size as original
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
for (int i = 0; i < original.Width; i++)
{
for (int j = 0; j < original.Height; j++)
{
//get the pixel from the original image
Color originalColor = original.GetPixel(i, j);
//create the grayscale version of the pixel
int grayScale = (int)((originalColor.R * .3) + (originalColor.G * .59)
+ (originalColor.B * .11));
//create the color object
Color newColor = Color.FromArgb(grayScale, grayScale, grayScale);
//set the new image's pixel to the grayscale version
newBitmap.SetPixel(i, j, newColor);
}
}
return newBitmap;
}
You could probably modify the palette to have only black and white on the image

Categories

Resources