As you know I am really interested in image processing.
For my first step, I wrote the program for reading image as double array in C#.
The code is imperfect but I think this will help someone's understand....
Here is an example usage.
The image processing result of above example program.
The left image is original, the right image is the result image which is red value is removed.
Okay here is core code.
For my first step, I wrote the program for reading image as double array in C#.
The code is imperfect but I think this will help someone's understand....
Here is an example usage.
var original = Bitmap.FromFile(@"C:\temp\test.jpg"); double[,] values = new Bitmap(original).To2DimDoubleArray(); // image processing part! // let's do something fun :D - filtering, binalizing, etc. // for now, removing R value from the image. for (int i = 0, len = values.Length/values.GetLength(0); i < len; i++ ) { //values[0, i] = 0; // a values[1, i] = 0; // r //values[2, i] = 0; // g //values[3, i] = 0; // b } values .ToBitmap(original.Width, original.Height, PixelFormat.Format32bppArgb) .SaveImageAsJpeg(@"c:\temp\test2.jpg", 75);
The image processing result of above example program.
The left image is original, the right image is the result image which is red value is removed.
Okay here is core code.
namespace Utility { public static class ImageUtils { // *** to Bitmap *** public static Bitmap ToBitmap(this double[,] doubleArray, int width, int height, PixelFormat pixelFormat) { var bmp = new Bitmap(width, height, pixelFormat); var rect = new Rectangle(0, 0, bmp.Width, bmp.Height); var bmpData = bmp.LockBits(rect, ImageLockMode.WriteOnly, bmp.PixelFormat); var ptr = bmpData.Scan0; int bytes = Math.Abs(bmpData.Stride) * bmp.Height; var values = doubleArray.To1DimensionalArray(); Marshal.Copy(values, 0, ptr, bytes); bmp.UnlockBits(bmpData); return bmp; } // *** to 2 dimensional double array *** public static double[,] To2DimDoubleArray(this Bitmap bmp) { var pixelFormat = bmp.PixelFormat; // should switch based on pixel format! if (pixelFormat.HasFlag(PixelFormat.Format24bppRgb)) { return bmp.To2DimDoubleArray(3); } else if (pixelFormat.HasFlag(PixelFormat.Format32bppArgb)) { return bmp.To2DimDoubleArray(4); } else { throw new NotImplementedException("Unsupported type of image:" + pixelFormat); } } private static double[,] To2DimDoubleArray(this Bitmap bmp, int block) { var rect = new Rectangle(0, 0, bmp.Width, bmp.Height); var bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat); // Get the address of the first line. var ptr = bmpData.Scan0; // Declare an array to hold the bytes of the bitmap. int bytes = Math.Abs(bmpData.Stride) * bmp.Height; var rgbValues = new byte[bytes]; // Copy the RGB values into the array. Marshal.Copy(ptr, rgbValues, 0, bytes); // Unlock the bits. bmp.UnlockBits(bmpData); return rgbValues.To2DimensionalArray(block); } private static double[,] To2DimensionalArray(this byte[] source, int block) { int len = source.Length / block; var ret = new double[block, len]; int tail = block - 1; for (int i = 0, offset = 0; i < len; i++, offset = i * block) { for (int j = 0; j < block; j++) { ret[tail - j, i] = source[offset + j]; } } return ret; } private static byte[] To1DimensionalArray(this double[,] source) { int block = source.GetLength(0); var ret = new byte[source.Length * block]; int len = source.Length / block; int tail = block - 1; for (int i = 0, offset = 0; i < len; i++, offset = i * block) { for (int j = 0; j < block; j++) { ret[offset + j] = ToByte(source[tail - j, i]); } } return ret; } // does anyone know smarter (or faster) way to convert 0~255 double value to byte? private static byte ToByte(double raw) { if (raw > 255 || raw < 0) { throw new InvalidDataException("value should be in range [0, 255]"); } return BitConverter.GetBytes((int)Math.Floor(raw))[0]; } // these are helper methods for saving image as jpeg format public static readonly ImageCodecInfo JPEG_CODEC = GetEncoderInfo("image/jpeg"); public static readonly string JPEG_EXT = Path.GetExtension(JPEG_CODEC.FilenameExtension.Split(';')[0]).ToLower(); public static void SaveImageAsJpeg(this Image src, string fileName, int quality) { var eps = new EncoderParameters(1); var ep = new EncoderParameter(Encoder.Quality, quality); eps.Param[0] = ep; src.Save(fileName.ChangeExtension("jpg"), JPEG_CODEC, eps); } } }
コメント
Display a notification icon in the system tray