163 lines
6.3 KiB
C#
163 lines
6.3 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Drawing;
|
|||
|
|
using System.Runtime.InteropServices;
|
|||
|
|
using System.Drawing.Imaging;
|
|||
|
|
namespace ShapeControl
|
|||
|
|
{
|
|||
|
|
public class CBitmapOps
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
public static Bitmap DoBitOpsForBitmap(Bitmap m1, Bitmap m2, string ops)
|
|||
|
|
{
|
|||
|
|
//assuming m1 and m2 are same width and height
|
|||
|
|
//direct bit manipulation
|
|||
|
|
|
|||
|
|
//get the max size, fill default white
|
|||
|
|
int m3h, m3w;
|
|||
|
|
m3h = (m1.Height > m2.Height ? m1.Height : m2.Height);
|
|||
|
|
m3w = (m1.Width > m2.Width ? m1.Width : m2.Width);
|
|||
|
|
|
|||
|
|
Bitmap m3 = new Bitmap(m3w, m3h, m1.PixelFormat);
|
|||
|
|
Graphics.FromImage(m3).FillRectangle(new SolidBrush(Color.White), 0, 0, m3w, m3h);
|
|||
|
|
|
|||
|
|
Rectangle rect1 = new Rectangle(0, 0, m1.Width, m1.Height);
|
|||
|
|
Rectangle rect2 = new Rectangle(0, 0, m2.Width, m2.Height);
|
|||
|
|
Rectangle rect3 = new Rectangle(0, 0, m3.Width, m3.Height);
|
|||
|
|
|
|||
|
|
BitmapData bmpData1 =
|
|||
|
|
m1.LockBits(rect1, ImageLockMode.ReadOnly,
|
|||
|
|
m1.PixelFormat);
|
|||
|
|
BitmapData bmpData2 =
|
|||
|
|
m2.LockBits(rect2, ImageLockMode.ReadOnly,
|
|||
|
|
m2.PixelFormat);
|
|||
|
|
BitmapData bmpData3 =
|
|||
|
|
m3.LockBits(rect3, ImageLockMode.ReadWrite,
|
|||
|
|
m3.PixelFormat);
|
|||
|
|
IntPtr ptr1 = bmpData1.Scan0;
|
|||
|
|
IntPtr ptr2 = bmpData2.Scan0;
|
|||
|
|
IntPtr ptr3 = bmpData3.Scan0;
|
|||
|
|
|
|||
|
|
int bytes1 = m1.Width * m1.Height * 4;
|
|||
|
|
int bytes2 = m2.Width * m2.Height * 4;
|
|||
|
|
int bytes3 = m3.Width * m3.Height * 4;
|
|||
|
|
|
|||
|
|
byte[] rgbValues1 = new byte[bytes1];
|
|||
|
|
byte[] rgbValues2 = new byte[bytes2];
|
|||
|
|
byte[] rgbValues3 = new byte[bytes3];
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//byte r = 0, g = 0, b = 0;
|
|||
|
|
// Copy the RGB values into the array.
|
|||
|
|
System.Runtime.InteropServices.Marshal.Copy(ptr1, rgbValues1, 0, bytes1);
|
|||
|
|
System.Runtime.InteropServices.Marshal.Copy(ptr2, rgbValues2, 0, bytes2);
|
|||
|
|
System.Runtime.InteropServices.Marshal.Copy(ptr3, rgbValues3, 0, bytes3);
|
|||
|
|
/*
|
|||
|
|
if(ops.Equals("xor"))
|
|||
|
|
for (int j = 0; j < m1.Height; j++)
|
|||
|
|
for (int i = 0; i < m1.Width; i++)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
int index = CoordsToIndex(i, j, bmpData1.Stride);
|
|||
|
|
rgbValues3[index] = (byte)((int)rgbValues1[index] ^ (int)rgbValues2[index]);
|
|||
|
|
rgbValues3[index + 1] = (byte)((int)rgbValues1[index+1] ^ (int)rgbValues2[index+1]);
|
|||
|
|
rgbValues3[index + 2] = (byte)((int)rgbValues1[index+2] ^ (int)rgbValues2[index+2]);
|
|||
|
|
rgbValues3[index + 3] = (byte)((int)rgbValues1[index + 3]) ;
|
|||
|
|
}
|
|||
|
|
*/
|
|||
|
|
// if (ops.Equals("AND"))
|
|||
|
|
// {
|
|||
|
|
for (int j = 0; j < m1.Height; j++)
|
|||
|
|
for (int i = 0; i < m1.Width; i++)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
int index = CoordsToIndex(i, j, bmpData1.Stride);
|
|||
|
|
int index3 = CoordsToIndex(i, j, bmpData3.Stride);
|
|||
|
|
|
|||
|
|
rgbValues3[index3] = rgbValues1[index];
|
|||
|
|
rgbValues3[index3 + 1] = rgbValues1[index + 1];
|
|||
|
|
rgbValues3[index3 + 2] = rgbValues1[index + 2];
|
|||
|
|
rgbValues3[index3 + 3] = rgbValues1[index + 3];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int j = 0; j < m2.Height; j++)
|
|||
|
|
for (int i = 0; i < m2.Width; i++)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
int index = CoordsToIndex(i, j, bmpData2.Stride);
|
|||
|
|
int index3 = CoordsToIndex(i, j, bmpData3.Stride);
|
|||
|
|
|
|||
|
|
switch (ops)
|
|||
|
|
{
|
|||
|
|
case "AND":
|
|||
|
|
rgbValues3[index3] = (byte)((int)rgbValues3[index3] & (int)rgbValues2[index]);
|
|||
|
|
rgbValues3[index3 + 1] = (byte)((int)rgbValues3[index3 + 1] & (int)rgbValues2[index + 1]);
|
|||
|
|
rgbValues3[index3 + 2] = (byte)((int)rgbValues3[index3 + 2] & (int)rgbValues2[index + 2]);
|
|||
|
|
rgbValues3[index3 + 3] = (byte)((int)rgbValues2[index + 3]);
|
|||
|
|
break;
|
|||
|
|
case "OR":
|
|||
|
|
rgbValues3[index3] = (byte)((int)rgbValues3[index3] | (int)rgbValues2[index]);
|
|||
|
|
rgbValues3[index3 + 1] = (byte)((int)rgbValues3[index3 + 1] | (int)rgbValues2[index + 1]);
|
|||
|
|
rgbValues3[index3 + 2] = (byte)((int)rgbValues3[index3 + 2] | (int)rgbValues2[index + 2]);
|
|||
|
|
rgbValues3[index3 + 3] = (byte)((int)rgbValues2[index + 3]);
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
System.Runtime.InteropServices.Marshal.Copy(rgbValues3, 0, ptr3, bytes3);
|
|||
|
|
// Unlock the bits.
|
|||
|
|
m1.UnlockBits(bmpData1);
|
|||
|
|
m2.UnlockBits(bmpData2);
|
|||
|
|
m3.UnlockBits(bmpData3);
|
|||
|
|
return m3;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//for argb color pixel format
|
|||
|
|
private static int CoordsToIndex(int x, int y, int stride)
|
|||
|
|
{
|
|||
|
|
return (stride * y) + (x * 4);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static void DoInvertBitmap(Bitmap bm)
|
|||
|
|
{
|
|||
|
|
//direct bit manipulation
|
|||
|
|
Rectangle rect = new Rectangle(0, 0, bm.Width, bm.Height);
|
|||
|
|
BitmapData bmpData =
|
|||
|
|
bm.LockBits(rect, ImageLockMode.ReadWrite,
|
|||
|
|
bm.PixelFormat);
|
|||
|
|
IntPtr ptr = bmpData.Scan0;
|
|||
|
|
int bytes = bm.Width * bm.Height * 4;
|
|||
|
|
byte[] rgbValues = new byte[bytes];
|
|||
|
|
//byte r = 0, g = 0, b = 0;
|
|||
|
|
// Copy the RGB values into the array.
|
|||
|
|
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
|
|||
|
|
|
|||
|
|
|
|||
|
|
for (int j = 0; j < bm.Height; j++)
|
|||
|
|
for (int i = 0; i < bm.Width; i++)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
int index = CoordsToIndex(i, j, bmpData.Stride);
|
|||
|
|
rgbValues[index] = (byte)(255 - rgbValues[index]);
|
|||
|
|
rgbValues[index + 1] = (byte)(255 - rgbValues[index + 1]);
|
|||
|
|
rgbValues[index + 2] = (byte)(255 - rgbValues[index + 2]);
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
|
|||
|
|
// Unlock the bits.
|
|||
|
|
bm.UnlockBits(bmpData);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|