private void button4_Click(object sender, EventArgs e)
{
string originalPathFile = #"C:\Users\user\Downloads\CaptchaCollection\Small\Sorting\";
string newPathFile = #"C:\Users\user\Downloads\CaptchaCollection\Small\Sorted\";
bool endInner = false;
int count2 = 1;
while (!endInner)
{
var files = Directory.GetFiles(originalPathFile).Select(nameWithExtension => Path.GetFileNameWithoutExtension(nameWithExtension)).Where(name => { int number; return int.TryParse(name, out number); }).Select(name => int.Parse(name)).OrderBy(number => number).ToArray();
Bitmap im1 = new Bitmap(originalPathFile + files[0].ToString() + ".png");
Bitmap im2 = new Bitmap(originalPathFile + files[count2].ToString() + ".png");
if (compare(im1, im2))
{
// if it's equal
File.Move(originalPathFile + files[count2].ToString() + ".png", newPathFile + files[count2].ToString() + ".png");
MessageBox.Show(files[count2].ToString() + " was removed");
}
if (count2 >= files.Length - 1) // checks if reached last file in directory
{
endInner = true;
}
count2++;
}
}
This is my button that will move all visually duplicated images comparing the first index (will make a nested one to go to next image and so on later). I create 2 path file strings. Then I use a while loop just to check if my count has reached the amount of files in the directory. After that it will end the loop.
private bool compare(Bitmap bmp1, Bitmap bmp2)
{
bool equals = true;
Rectangle rect = new Rectangle(0, 0, bmp1.Width, bmp1.Height);
BitmapData bmpData1 = bmp1.LockBits(rect, ImageLockMode.ReadOnly, bmp1.PixelFormat);
BitmapData bmpData2 = bmp2.LockBits(rect, ImageLockMode.ReadOnly, bmp2.PixelFormat);
unsafe
{
byte* ptr1 = (byte*)bmpData1.Scan0.ToPointer();
byte* ptr2 = (byte*)bmpData2.Scan0.ToPointer();
int width = rect.Width * 3; // for 24bpp pixel data
for (int y = 0; equals && y < rect.Height; y++)
{
for (int x = 0; x < width; x++)
{
if (*ptr1 != *ptr2)
{
equals = false;
break;
}
ptr1++;
ptr2++;
}
ptr1 += bmpData1.Stride - width;
ptr2 += bmpData2.Stride - width;
}
}
bmp1.UnlockBits(bmpData1);
bmp2.UnlockBits(bmpData2);
return equals;
}
This method checks visually if an image is duplicated. Returns true if it is.
I'm getting this exception:
The process cannot access the file because it is being used by another process.
It occurred on this line:
File.Move(originalPathFile + files[count2].ToString() + ".png", newPathFile + files[count2].ToString() + ".png");
When you open file using new Bitmap(fileName) you can't move file because it is in use.
So dispose first that object and then try to move file. You can also use following approch where you can send filename instead of Bitmap and in compare function use using keywork which will automatically dispose object.
compare(originalPathFile + files[0].ToString() + ".png", originalPathFile + files[count2].ToString() + ".png")
private bool compare(String bmp1Path, String bmp2Path)
{
bool equals = true;
Rectangle rect = new Rectangle(0, 0, bmp1.Width, bmp1.Height);
using(Bitmap im1 = new Bitmap(bmp1Path)
{
using(Bitmap im2 = new Bitmap(bmp2Path)
{
BitmapData bmpData1 = bmp1.LockBits(rect, ImageLockMode.ReadOnly, bmp1.PixelFormat);
BitmapData bmpData2 = bmp2.LockBits(rect, ImageLockMode.ReadOnly, bmp2.PixelFormat);
unsafe
{
byte* ptr1 = (byte*)bmpData1.Scan0.ToPointer();
byte* ptr2 = (byte*)bmpData2.Scan0.ToPointer();
int width = rect.Width * 3; // for 24bpp pixel data
for (int y = 0; equals && y < rect.Height; y++)
{
for (int x = 0; x < width; x++)
{
if (*ptr1 != *ptr2)
{
equals = false;
break;
}
ptr1++;
ptr2++;
}
ptr1 += bmpData1.Stride - width;
ptr2 += bmpData2.Stride - width;
}
}
bmp1.UnlockBits(bmpData1);
bmp2.UnlockBits(bmpData2);
}
}
return equals;
}
Related
I have this part of code which converts a bitmap with 32bppArgb pixel format to an 1d byte[] array:
using (var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb))
{
var boundsRect = new Rectangle(0, 0, width, height);
// Copy pixels from screen capture Texture to GDI bitmap
var mapDest = bitmap.LockBits(boundsRect, ImageLockMode.ReadOnly, bitmap.PixelFormat);
var sourcePtr = mapSource.DataPointer;
var destPtr = mapDest.Scan0;
for (int y = 0; y < height; y++)
{
// Copy a single line
Utilities.CopyMemory(destPtr, sourcePtr, width * 4);
// Advance pointers
sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
destPtr = IntPtr.Add(destPtr, mapDest.Stride);
}
// Release source and dest locks
bitmap.UnlockBits(mapDest);
device.ImmediateContext.UnmapSubresource(screenTexture, 0);
using (var ms = new MemoryStream())
{
bitmap.Save(ms, ImageFormat.Bmp);
ScreenRefreshed?.Invoke(this, ms.ToArray());
_init = true;
}
}
I call my function ReplacePixels() to read and replace rgba values like this:
data = ReplacePixels(data);
data is byte[] array received from code above.
The example function which i use but without success:
private byte[] ReplacePixels (byte[] data)
{
int width = Screen.PrimaryScreen.Bounds.Width;
int height = Screen.PrimaryScreen.Bounds.Height;
Int32 curRowOffs = 0;
Int32 stride = 4 * (width * 4 + 31) / 32;
try
{
for (uint y = 0; y < height; y++)
{
// Set offset to start of current row
Int32 curOffs = curRowOffs;
for (uint x = 0; x < width; x++)
{
// ARGB = bytes [B,G,R,A]
var b = data[curOffs];
var g = data[curOffs + 1];
var r = data[curOffs + 2];
var a = data[curOffs + 3];
//bgra changes here..
//apply bgra values
data[offset] = Convert.ToByte(b);
data[offset + 1] = Convert.ToByte(g);
data[offset + 2] = Convert.ToByte(r);
data[offset + 3] = Convert.ToByte(a);
// Increase offset to next colour
curOffs += 4;
}
// Increase row offset
curRowOffs += stride;
}
}
catch (System.Exception e)
{
Debug.WriteLine(e);
}
return data;
}
The question is: how can i read and replace the argb values from this array?
Edit: this is the solution that i found
public byte[] ReplacePixels(byte[] data)
{
int width = Screen.PrimaryScreen.Bounds.Width;
int height = Screen.PrimaryScreen.Bounds.Height;
Int32 stride = width * 4;
Int32 curRowOffs = (((width * height * 4) + 54) - 1) - stride;
for (uint y = 0; y < height; y++)
{
uint index = (uint)curRowOffs;
for (uint x = 0; x < width; x++)
{
// ARGB = bytes [B,G,R,A]
if (index >= 0)
{
//var rgba = GetRGB(data, index);
var b = data[index];
var g = data[index + 1];
var r = data[index + 2];
var a = data[index + 3];
//bgra changes here...
data[index] = b;
data[index + 1] = g;
data[index + 2] = r;
data[index + 3] = a;
}
index += 4;
}
curRowOffs -= stride;
}
return data;
}
enter image description here
Please give me a solution about that I have ti find out many site's but i did not get any solution.
thankyou
private void Form1_Load(object sender, EventArgs e)
{
Bitmap bitmap = new Bitmap(#"D:\shapes_Images\4.png");
pictureBox1.Image = bitmap;
image = bitmap ;
}
Bitmap image;
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
//Create a path and add lines.
List<Point> outlinePoints = new List<Point>();
BitmapData bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
byte[] originalBytes = new byte[image.Width * image.Height * 4];
Marshal.Copy(bitmapData.Scan0, originalBytes, 0, originalBytes.Length);
//find non-transparent pixels visible from the top of the image
for (int x = 0; x < bitmapData.Width; x++)
{
for (int y = 0; y < bitmapData.Height; y++)
{
byte alpha = originalBytes[y * bitmapData.Stride + 4 * x + 3];
if (alpha != 0)
{
Point p = new Point(x, y);
if (!ContainsPoint(outlinePoints, p))
outlinePoints.Add(p);
break;
}
}
}
//helper variable for storing position of the last pixel visible from both sides
//or last inserted pixel
int? lastInsertedPosition = null;
//find non-transparent pixels visible from the right side of the image
for (int y = 0; y < bitmapData.Height; y++)
{
for (int x = bitmapData.Width - 1; x >= 0; x--)
{
byte alpha = originalBytes[y * bitmapData.Stride + 4 * x + 3];
if (alpha != 0)
{
Point p = new Point(x, y);
if (!ContainsPoint(outlinePoints, p))
{
if (lastInsertedPosition.HasValue)
{
outlinePoints.Insert(lastInsertedPosition.Value + 1, p);
lastInsertedPosition += 1;
}
else
{
outlinePoints.Add(p);
}
}
else
{
//save last common pixel from visible from more than one sides
lastInsertedPosition = outlinePoints.IndexOf(p);
}
break;
}
}
}
lastInsertedPosition = null;
//find non-transparent pixels visible from the bottom of the image
for (int x = bitmapData.Width - 1; x >= 0; x--)
{
for (int y = bitmapData.Height - 1; y >= 0; y--)
{
byte alpha = originalBytes[y * bitmapData.Stride + 4 * x + 3];
if (alpha != 0)
{
Point p = new Point(x, y);
if (!ContainsPoint(outlinePoints, p))
{
if (lastInsertedPosition.HasValue)
{
outlinePoints.Insert(lastInsertedPosition.Value + 1, p);
lastInsertedPosition += 1;
}
else
{
outlinePoints.Add(p);
}
}
else
{
//save last common pixel from visible from more than one sides
lastInsertedPosition = outlinePoints.IndexOf(p);
}
break;
}
}
}
lastInsertedPosition = null;
//find non-transparent pixels visible from the left side of the image
for (int y = bitmapData.Height - 1; y >= 0; y--)
{
for (int x = 0; x < bitmapData.Width; x++)
{
byte alpha = originalBytes[y * bitmapData.Stride + 4 * x + 3];
if (alpha != 0)
{
Point p = new Point(x, y);
if (!ContainsPoint(outlinePoints, p))
{
if (lastInsertedPosition.HasValue)
{
outlinePoints.Insert(lastInsertedPosition.Value + 1, p);
lastInsertedPosition += 1;
}
else
{
outlinePoints.Add(p);
}
}
else
{
//save last common pixel from visible from more than one sides
lastInsertedPosition = outlinePoints.IndexOf(p);
}
break;
}
}
}
// Added to close the loop
outlinePoints.Add(outlinePoints[0]);
image.UnlockBits(bitmapData);
GraphicsPath myPath = new GraphicsPath();
myPath.AddLines(outlinePoints.ToArray());
// return outlinePoints.ToArray();
PathGradientBrush pthGrBrush = new PathGradientBrush(outlinePoints.ToArray());
//foreach (Point p in outlinePoints.ToArray())
//{
// //Point p1 = p;
//}
Color[] colors = { Color.Red , Color.Green };
pthGrBrush.SurroundColors = colors;
pthGrBrush.CenterColor = Color.Red;
Blend blend = new Blend();
// blend.Factors = new float[] { 1, 0 };
blend.Positions = new float[] { 0, 0.25f };
pthGrBrush.Blend = blend;
// LinearGradientBrush linGrBrush = new LinearGradientBrush(new Point(0, 10),new Point(200, 10),Color.FromArgb(255, 255, 0, 0),Color.FromArgb(255, 0, 0, 255));
e.Graphics.FillPath(pthGrBrush, myPath);
// Pen myPen = new Pen(Color.Black, 6);
// e.Graphics.DrawPath(pthGrBrush, myPath);
}
I have written a code that converts image to grayscale. but the code only convert partial of it.
I am trying to convert this code to a Parallel computation. I end up with bugs that I can not get my head around them. Any suggestion?
private void button2_Click(object sender, EventArgs e)
{
Bitmap bmp = (Bitmap)pictureBox1.Image;
unsafe {
//get image dimension
//int width = bmp.Width;
//int height = bmp.Height;
BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
//define variable
int bpp = System.Drawing.Bitmap.GetPixelFormatSize(bmp.PixelFormat) / 8;
int hip = bitmapData.Height;
int wib = bitmapData.Width + bpp;
//point to first pixel
byte* PtrFirstPixel = (byte*)bitmapData.Scan0;
//color of pixel
// Color p;
//grayscale
Parallel.For(0, hip, y =>
{
byte* currentLine = PtrFirstPixel + (y * bitmapData.Stride);
for (int x = 0; x < wib; x = x + bpp)
{
//get pixel value
//p = bmp.GetPixel(x, y);
//extract pixel component ARGB
//int a = p.A;
//int r = p.R;
//int g = p.G;
// int b = p.B;
int b = currentLine[x];
int g = currentLine[x + 1];
int r = currentLine[x + 2];
//find average
int avg = (r + g + b) / 3;
//set new pixel value
// bmp.SetPixel(x, y, Color.FromArgb(a, avg, avg, avg));
currentLine[x] = (byte)avg;
currentLine[x + 1] = (byte)avg;
currentLine[x + 2] = (byte)avg;
}
});
bmp.UnlockBits(bitmapData);
//load grayscale image in picturebox2
//pictureBox2.Image = bmp;
}
pictureBox2.Image = bmp;
}
my out put image
int wib = bitmapData.Width + bpp;
should be:
int wib = bitmapData.Width * bpp;
You want the number of bytes which requires a multiply, not an add. There may be other issues, but this is definitely incorrect.
the sample panorama image url https://upload.wikimedia.org/wikipedia/commons/3/3b/360%C2%B0_Hoher_Freschen_Panorama_2.jpg which i saved in my pc and generate tile from that image programmatically and got
error like out of memory
this line throw the error Bitmap bmLevelSource =
(Bitmap)Bitmap.FromFile(levelSourceImage);
here is my program code in c# which throw the error
double maxZoom = 5;
string FILEPATH = #"C:\test\img.jpg";
string TARGETFOLDER = #"C:\test\Src";
bool REMOVEXISTINGFILES = true;
if (!System.IO.File.Exists(FILEPATH))
{
Console.WriteLine("file not exist");
return;
}
if (maxZoom >= 10)
{
Console.WriteLine("Scale multiplier should be an integer <=10");
return;
}
//Read image
Bitmap bmSource;
try
{
bmSource = (Bitmap)Bitmap.FromFile(FILEPATH);
}
catch
{
Console.WriteLine("image file not valid");
return;
}
//check directory exist
if (!System.IO.Directory.Exists(TARGETFOLDER))
{
System.IO.Directory.CreateDirectory(TARGETFOLDER);
}
else if (REMOVEXISTINGFILES)
{
string[] files = System.IO.Directory.GetFiles(TARGETFOLDER);
foreach (string file in files)
System.IO.File.Delete(file);
string[] dirs = System.IO.Directory.GetDirectories(TARGETFOLDER);
foreach (string dir in dirs)
System.IO.Directory.Delete(dir, true);
}
int actualHeight = bmSource.Height;
int actualWidth = bmSource.Width;
if (((actualHeight % 256) != 0)
||
((actualWidth % 256) != 0))
{
Console.WriteLine("image width and height pixels should be multiples of 256");
return;
}
int actualResizeSizeWidth = 1;
int level = 0;
while (level <= maxZoom)
{
string leveldirectory = System.IO.Path.Combine(TARGETFOLDER, String.Format("{0}", level));
if (!System.IO.Directory.Exists(leveldirectory))
System.IO.Directory.CreateDirectory(leveldirectory);
int rowsInLevel = Convert.ToInt32(Math.Pow(2, level));
actualResizeSizeWidth = 256 * rowsInLevel;
//create image to parse
int actualResizeSizeHeight = (actualHeight * actualResizeSizeWidth) / actualWidth;
Bitmap resized = new Bitmap(bmSource, new Size(actualResizeSizeWidth, actualResizeSizeHeight));
string levelSourceImage = System.IO.Path.Combine(leveldirectory, "level.png");
resized.Save(levelSourceImage);
for (int x = 0; x < rowsInLevel; x++)
{
string levelrowdirectory = System.IO.Path.Combine(leveldirectory, String.Format("{0}", x));
if (!System.IO.Directory.Exists(levelrowdirectory))
System.IO.Directory.CreateDirectory(levelrowdirectory);
Bitmap bmLevelSource = (Bitmap)Bitmap.FromFile(levelSourceImage);
//generate tiles
int numberTilesHeight = Convert.ToInt32(Math.Ceiling(actualResizeSizeHeight / 256.0));
for (int y = 0; y < numberTilesHeight; y++)
{
Console.WriteLine("Generating Tiles " + level.ToString() + " " + x.ToString() + " " + y.ToString()); int heightToCrop = actualResizeSizeHeight >= 256 ? 256 : actualResizeSizeHeight;
Rectangle destRect = new Rectangle(x * 256, y * 256, 256, heightToCrop);
//croped
Bitmap bmTile = bmLevelSource.Clone(destRect, System.Drawing.Imaging.PixelFormat.DontCare);
//full tile
Bitmap bmFullTile = new Bitmap(256, 256);
Graphics gfx = Graphics.FromImage(bmFullTile);
gfx.DrawImageUnscaled(bmTile, 0, 0);
bmFullTile.Save(System.IO.Path.Combine(levelrowdirectory, String.Format("{0}.png", y)));
bmFullTile.Dispose();
bmTile.Dispose();
}
}
level++;
}
i comment the below code when i run the program
if (((actualHeight % 256) != 0)
||
((actualWidth % 256) != 0))
{
Console.WriteLine("image width and height pixels should be multiples of 256");
return;
}
what is the fault for which i got the error called "Out of Memory"
Thanks
Edit
actual image height and width was 1250 and 2500.
actualResizeSizeWidth 256
actualResizeSizeHeight 128
i include a panorama image url in this post at top. can u plzz download url and execute my code at your end to see memory issue is coming?
Code Update
i modify the code a bit and dispose some Bitmap.
dispose like this way
bmLevelSource.Dispose(); and resized.Dispose();
while (level <= maxZoom)
{
string leveldirectory = System.IO.Path.Combine(TARGETFOLDER, String.Format("{0}", level));
if (!System.IO.Directory.Exists(leveldirectory))
System.IO.Directory.CreateDirectory(leveldirectory);
int rowsInLevel = Convert.ToInt32(Math.Pow(2, level));
actualResizeSizeWidth = 256 * rowsInLevel;
//create image to parse
int actualResizeSizeHeight = (actualHeight * actualResizeSizeWidth) / actualWidth;
Bitmap resized = new Bitmap(bmSource, new Size(actualResizeSizeWidth, actualResizeSizeHeight));
string levelSourceImage = System.IO.Path.Combine(leveldirectory, "level.png");
resized.Save(levelSourceImage);
for (int x = 0; x < rowsInLevel; x++)
{
string levelrowdirectory = System.IO.Path.Combine(leveldirectory, String.Format("{0}", x));
if (!System.IO.Directory.Exists(levelrowdirectory))
System.IO.Directory.CreateDirectory(levelrowdirectory);
Bitmap bmLevelSource = (Bitmap)Bitmap.FromFile(levelSourceImage);
//generate tiles
int numberTilesHeight = Convert.ToInt32(Math.Ceiling(actualResizeSizeHeight / 256.0));
for (int y = 0; y < numberTilesHeight; y++)
{
Console.WriteLine("Generating Tiles " + level.ToString() + " " + x.ToString() + " " + y.ToString()); int heightToCrop = actualResizeSizeHeight >= 256 ? 256 : actualResizeSizeHeight;
Rectangle destRect = new Rectangle(x * 256, y * 256, 256, heightToCrop);
//croped
Bitmap bmTile = bmLevelSource.Clone(destRect, System.Drawing.Imaging.PixelFormat.DontCare);
//full tile
Bitmap bmFullTile = new Bitmap(256, 256);
Graphics gfx = Graphics.FromImage(bmFullTile);
gfx.DrawImageUnscaled(bmTile, 0, 0);
bmFullTile.Save(System.IO.Path.Combine(levelrowdirectory, String.Format("{0}.png", y)));
bmFullTile.Dispose();
bmTile.Dispose();
}
bmLevelSource.Dispose();
}
level++;
resized.Dispose();
}
please see my bit modified code and give suggestion now.
Hi i m really new in image processing in C# and the code below basically getpixel from the image I browsed from my computer and will compare the RGB value of the pixel with the right pixel and if its the same value, it will setpixel to cyan color. the problem is with the getpixel, it is really very slow even on a small resolution photos and I'm also looking to add more function to it. I have read about lockbits and was trying it out but was unable to successfully write the code.
namespace Disimage
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Bitmap pic;
public Bitmap pic2;
private bool compare_colour_constant(int original, int sample)
{
if (original == sample)
return true;
else
return false;
}
public void btn_browse_Click_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp)|*.jpg; *.jpeg; *.gif; *.bmp";
if (open.ShowDialog() == DialogResult.OK)
{
pic = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
pic2 = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
//pictureBox1.Image = new Bitmap(open.FileName);
pic = new Bitmap(open.FileName);
pic2 = new Bitmap(open.FileName);
pictureBox1.Image = pic;
pictureBox2.Image = pic2;
pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
textBox1.Text = open.FileName;
pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
}
}
catch (Exception)
{
throw new ApplicationException("Failed loading image");
}
}
public void scan_Click(object sender, EventArgs e)
{
try
{
//Bitmap pic = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
//Bitmap pic2 = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
pictureBox1.Image = pic;
pictureBox2.Image = pic2;
progressBar1.Minimum = 0;
progressBar1.Maximum = pic.Width;
int []RGB = pic.GetPixel();
for (int w = 1; w < pic.Width - 1; w++)
{
progressBar1.Step = 1;
progressBar1.PerformStep();
if (progressBar1.Value == progressBar1.Maximum)
progressBar1.Value = 0;
for (int h = 1; h < pic.Height - 1; h++)
{
int red = pic.GetPixel(w, h).R;
int green = pic.GetPixel(w, h).G;
int blue = pic.GetPixel(w, h).B;
int colour = pic.GetPixel(w, h).R + pic.GetPixel(w, h).G + pic.GetPixel(w, h).B;
int colour2 = pic.GetPixel(w + 1, h).R + pic.GetPixel(w + 1, h).G + pic.GetPixel(w + 1, h).B;
/*textBox2.Text = red.ToString();
textBox3.Text = green.ToString();
textBox4.Text = blue.ToString();
*/
int Lred = pic.GetPixel(w - 1, h).R;
int Lgreen = pic.GetPixel(w - 1, h).G;
int Lblue = pic.GetPixel(w - 1, h).B;
int Rred = pic.GetPixel(w + 1, h).R;
int Rgreen = pic.GetPixel(w + 1, h).G;
int Rblue = pic.GetPixel(w + 1, h).B;
if (compare_colour_constant(colour, colour2) == true)
pic2.SetPixel(w, h, Color.Cyan);
}
}
}
catch (Exception)
{
throw new ApplicationException("Failed loading image");
}
}
}
}
Though a little late, I'd be happy to answer your question for other users. The first thing you would need to do is to declare a BitmapData variable, which would hold (obviously) the data from the Bitmap image that has been placed into the memory. To do this:
System.Drawing.Imaging.BitmapData bmpdata = pic.LockBits(new Rectangle(pictureBox1.Location.X, pictureBox1.Location.Y, pictureBox1.Width, pictureBox1.Height),
System.Drawing.Imaging.ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat);
After calling this code, you can proceed to edit the BitmapData to your liking. In this situation you could call for a loop through a byte array of the Data and compare the RGB to the RGB of the pixel immediately to the right's and determine similarity. Example:
unsafe
{
for (int y = 0; y < bmpdata.Height; y++) // Repeats for each row
{
byte* row = (byte*)bmpdata.Scan0 + (y * bmpdata.Stride); // Array of bytes for the current row of pixels
for (int x = 0; x < bmpdata.Width; x++) // Repeats for each pixel on each row
{
if (row[x * 4] == row[(x + 1) * 4] && row[(x * 4) + 1] == row[((x + 1) * 4) + 1] && row[(x * 4) + 2] == row[((x + 1) * 4) + 2])
{
row[x * 4] = 255; // Blue value of current pixel
row[(x * 4) + 1] = 255; // Green Value of current pixel
row[(x * 4) + 2] = 0; // Red value of current pixel
}
}
}
}
ATTENTION: Though the above might work (and let me stress might), it would probably be much more reliable to go to Bob Powell's site and read his page on LockBits. Though it may be hard to understand at first, it gets simpler as you go along. His page is much more detailed than I could be in this answer, and he probably has working examples.