📄 imagequantizer.cs
字号:
namespace Imps.Utils
{
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
public abstract class ImageQuantizer
{
private bool _singlePass;
public ImageQuantizer(bool singlePass)
{
this._singlePass = singlePass;
}
protected virtual unsafe void FirstPass(BitmapData sourceData, int width, int height)
{
byte* numPtr = (byte*) sourceData.Scan0.ToPointer();
for (int i = 0; i < height; i++)
{
int* numPtr2 = (int*) numPtr;
int num2 = 0;
while (num2 < width)
{
this.InitialQuantizePixel((Color32*) numPtr2);
num2++;
numPtr2++;
}
numPtr += sourceData.Stride;
}
}
protected abstract ColorPalette GetPalette(ColorPalette original);
protected virtual unsafe void InitialQuantizePixel(Color32* pixel)
{
}
public Bitmap Quantize(Image source)
{
int height = source.Height;
int width = source.Width;
Rectangle rect = new Rectangle(0, 0, width, height);
Bitmap image = new Bitmap(width, height, PixelFormat.Format32bppArgb);
Bitmap output = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
using (Graphics graphics = Graphics.FromImage(image))
{
graphics.PageUnit = GraphicsUnit.Pixel;
graphics.DrawImageUnscaled(source, rect);
}
BitmapData sourceData = null;
try
{
sourceData = image.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
if (!this._singlePass)
{
this.FirstPass(sourceData, width, height);
}
output.Palette = this.GetPalette(output.Palette);
this.SecondPass(sourceData, output, width, height, rect);
}
finally
{
image.UnlockBits(sourceData);
}
return output;
}
protected abstract unsafe byte QuantizePixel(Color32* pixel);
protected virtual unsafe void SecondPass(BitmapData sourceData, Bitmap output, int width, int height, Rectangle bounds)
{
BitmapData bitmapdata = null;
try
{
bitmapdata = output.LockBits(bounds, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
byte* numPtr = (byte*) sourceData.Scan0.ToPointer();
int* numPtr2 = (int*) numPtr;
int* numPtr3 = numPtr2;
byte* numPtr4 = (byte*) bitmapdata.Scan0.ToPointer();
byte* numPtr5 = numPtr4;
byte num = this.QuantizePixel((Color32*) numPtr2);
numPtr5[0] = num;
for (int i = 0; i < height; i++)
{
numPtr2 = (int*) numPtr;
numPtr5 = numPtr4;
int num3 = 0;
while (num3 < width)
{
if (numPtr3[0] != numPtr2[0])
{
num = this.QuantizePixel((Color32*) numPtr2);
numPtr3 = numPtr2;
}
numPtr5[0] = num;
num3++;
numPtr2++;
numPtr5++;
}
numPtr += sourceData.Stride;
numPtr4 += bitmapdata.Stride;
}
}
finally
{
output.UnlockBits(bitmapdata);
}
}
[StructLayout(LayoutKind.Explicit)]
public struct Color32
{
[FieldOffset(3)]
public byte Alpha;
[FieldOffset(0)]
public int ARGB;
[FieldOffset(0)]
public byte Blue;
[FieldOffset(1)]
public byte Green;
[FieldOffset(2)]
public byte Red;
public System.Drawing.Color Color
{
get
{
return System.Drawing.Color.FromArgb(this.Alpha, this.Red, this.Green, this.Blue);
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -