CSharp · Console
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TestTestTest
{
public partial class PictureBoxForm : Form
{
public PictureBoxForm()
{
InitializeComponent();
}
public PictureBoxForm(Bitmap image)
{
InitializeComponent();
this.pictureBox1.Image = image as System.Drawing.Image;
}
public PictureBoxForm(Bitmap image1, Bitmap image2)
{
InitializeComponent();
this.pictureBox1.Image = image1 as System.Drawing.Image;
this.pictureBox2.Image = image2 as System.Drawing.Image;
}
}
partial class PictureBoxForm
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.pictureBox2 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.pictureBox1.Location = new System.Drawing.Point(12, 12);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(600, 600);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// pictureBox2
//
this.pictureBox2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.pictureBox2.Location = new System.Drawing.Point(618, 12);
this.pictureBox2.Name = "pictureBox2";
this.pictureBox2.Size = new System.Drawing.Size(250, 250);
this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox2.TabIndex = 1;
this.pictureBox2.TabStop = false;
//
// PictureBoxForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(882, 625);
this.Controls.Add(this.pictureBox2);
this.Controls.Add(this.pictureBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "PictureBoxForm";
this.Text = "PictureBoxForm";
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.PictureBox pictureBox2;
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new FourierForm());
//Application.Run(new ConvolutionForm());
//Application.Run(new KassWitkinForm());
//KassWitkinImageOperation.Run();
BitmapLockerTest.Run();
}
}
public partial class Grayscale
{
public static unsafe Bitmap ToGrayscale(Bitmap bmColor)
{
int Width = bmColor.Width;
int Height = bmColor.Height;
Bitmap bmMono = new Bitmap(Width, Height, PixelFormat.Format8bppIndexed);
bmMono.SetResolution(bmColor.HorizontalResolution, bmColor.VerticalResolution);
///////////////////////////////////////
// Set grayscale palette
///////////////////////////////////////
ColorPalette colorPalette = bmMono.Palette;
for (int i = 0; i < colorPalette.Entries.Length; i++)
{
colorPalette.Entries[i] = Color.FromArgb(i, i, i);
}
bmMono.Palette = colorPalette;
BitmapData bmd = bmMono.LockBits(new Rectangle(Point.Empty, bmMono.Size), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
Byte* pPixel = (Byte*)bmd.Scan0;
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
Color clr = bmColor.GetPixel(x, y);
Byte byPixel = (byte)((30 * clr.R + 59 * clr.G + 11 * clr.B) / 100);
pPixel[x] = byPixel;
}
pPixel += bmd.Stride;
}
bmMono.UnlockBits(bmd);
return bmMono;
}
public static void SetGrayscalePalette(Bitmap image)
{
// check pixel format
if (image.PixelFormat == PixelFormat.Format8bppIndexed)
{
// get palette
ColorPalette cp = image.Palette;
// init palette
for (int i = 0; i < 256; i++)
{
cp.Entries[i] = Color.FromArgb(i, i, i);
}
// set palette back
image.Palette = cp;
}
else
{
throw new Exception("8 bit grayscaleImage required");
}
}
public static Bitmap CreateGrayscaleImage(int width, int height)
{
// create new image
Bitmap image = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
// set palette to grayscale
SetGrayscalePalette(image);
// return new image
return image;
}
public static bool IsGrayscale(Bitmap bitmap)
{
return bitmap.PixelFormat == PixelFormat.Format8bppIndexed ? true : false;
}
}
//http://www.codeproject.com/Tips/240428/Work-with-Bitmaps-Faster-in-Csharp
public class BitmapLocker
{
//private properties
Bitmap _bitmap = null;
bool _isLocked = false;
BitmapData _bitmapData = null;
private byte[] _imageData = null;
//public properties
public IntPtr IntegerPointer
{
get;
private set;
}
public int Width
{
get
{
return _bitmap.Width;
}
}
public int Height
{
get
{
return _bitmap.Height;
}
}
public int Stride
{
get
{
return _bitmapData.Stride;
}
}
public int ColorDepth
{
get
{
return Bitmap.GetPixelFormatSize(_bitmap.PixelFormat);
}
}
public int PaddingOffset
{
get
{
return _bitmapData.Stride - (_bitmap.Width * ColorDepth / 8);
}
}
public PixelFormat ImagePixelFormat
{
get
{
return _bitmap.PixelFormat;
}
}
public bool IsGrayscale
{
get
{
return Grayscale.IsGrayscale(_bitmap);
}
}
//Constructor
public BitmapLocker(Bitmap source)
{
IntegerPointer = IntPtr.Zero;
this._bitmap = source;
}
/// <summary>
/// Get the color of the specified pixel
/// </summary>
/// <param name = "x"></param>
/// <param name = "y"></param>
/// <returns></returns>
public Color GetPixel(int x, int y)
{
Color clr = Color.Empty;
// Get color components count
int cCount = ColorDepth / 8;
// Get start index of the specified pixel
int i = ((y * Width) + x) * cCount;
//int i = ((x * Width) + y) * cCount;
if (i > _imageData.Length - cCount)
throw new IndexOutOfRangeException();
if (ColorDepth == 32) // For 32 bpp get Red, Green, Blue and Alpha
{
byte b = _imageData[i];
byte g = _imageData[i + 1];
byte r = _imageData[i + 2];
byte a = _imageData[i + 3]; // a
clr = Color.FromArgb(a, r, g, b);
}
if (ColorDepth == 24) // For 24 bpp get Red, Green and Blue
{
byte b = _imageData[i];
byte g = _imageData[i + 1];
byte r = _imageData[i + 2];
clr = Color.FromArgb(r, g, b);
}
if (ColorDepth == 8)
// For 8 bpp get color value (Red, Green and Blue values are the same)
{
byte c = _imageData[i];
clr = Color.FromArgb(c, c, c);
}
return clr;
}
/// <summary>
/// Set the color of the specified pixel
/// </summary>
/// <param name = "x"></param>
/// <param name = "y"></param>
/// <param name = "color"></param>
public void SetPixel(int x, int y, Color color)
{
// Get color components count
int cCount = ColorDepth / 8;
// Get start index of the specified pixel
int i = ((y * Width) + x) * cCount;
//int i = ((x * Width) + y) * cCount;
if (ColorDepth == 32) // For 32 bpp set Red, Green, Blue and Alpha
{
_imageData[i] = color.B;
_imageData[i + 1] = color.G;
_imageData[i + 2] = color.R;
_imageData[i + 3] = color.A;
}
if (ColorDepth == 24) // For 24 bpp set Red, Green and Blue
{
_imageData[i] = color.B;
_imageData[i + 1] = color.G;
_imageData[i + 2] = color.R;
}
if (ColorDepth == 8)
{
// For 8 bpp set color value (Red, Green and Blue values are the same)
_imageData[i] = color.B;
string str = string.Empty;
}
}
/// Lock bitmap
public void Lock()
{
if (_isLocked == false)
{
try
{
// Lock bitmap (so that no movement of data by .NET framework) and return bitmap data
_bitmapData = _bitmap.LockBits(new Rectangle(0, 0, _bitmap.Width, _bitmap.Height), ImageLockMode.ReadWrite, _bitmap.PixelFormat);
// Create byte array to copy pixel values
int noOfBitsNeededForStorage = _bitmap.Width * _bitmap.Height;
_imageData = new byte[noOfBitsNeededForStorage * ColorDepth / 8]; //# of bytes needed for storage
IntegerPointer = _bitmapData.Scan0;
// Copy data from __IntegerPointer to PixelArray
Marshal.Copy(IntegerPointer, _imageData, 0, _imageData.Length);
_isLocked = true;
}
catch (Exception)
{
throw;
}
}
else
{
throw new Exception("Bitmap is already locked.");
}
}
/// Unlock bitmap
public void Unlock()
{
if (_isLocked == true)
{
try
{
// Copy data from PixelArray to __IntegerPointer
Marshal.Copy(_imageData, 0, IntegerPointer, _imageData.Length);
// Unlock bitmap data
_bitmap.UnlockBits(_bitmapData);
_isLocked = false;
}
catch (Exception)
{
throw;
}
}
else
{
throw new Exception("Bitmap is not locked.");
}
}
}
public class BitmapLockerTest
{
private static string path = @"locker.png";
public static void Run()
{
Bitmap image = Grayscale.ToGrayscale(Bitmap.FromFile(path) as Bitmap);
Bitmap canvas = Grayscale.CreateGrayscaleImage(1024, 256);
BitmapLocker imageLocker = new BitmapLocker(image);
BitmapLocker canvasLocker = new BitmapLocker(canvas);
imageLocker.Lock();
canvasLocker.Lock();
int startX = (Math.Abs(canvas.Width - image.Width) / 2);
int startY = (Math.Abs(canvas.Height - image.Height) / 2);
for (int y = startY; y < (startY + image.Height); y++)
{
for (int x = startX; x < (startX + image.Width); x++)
{
int xxx = x - startX;
int yyy = y - startY;
canvasLocker.SetPixel(x, y, imageLocker.GetPixel(xxx, yyy));
}
}
canvasLocker.Unlock();
imageLocker.Unlock();
new PictureBoxForm(canvas, image).ShowDialog();
}
}
}