В настоящее время я пытаюсь преобразовать растровое изображение в двоичное изображение.Я беру среднее значение пикселя, и если оно ниже определенного порога, пиксель будет либо 1, либо 0. Я знаю, как заставить это работать с текстовым файлом.Но я пытаюсь создать образ из нулей и единиц.Таким образом, каждый пиксель будет преобразован в растровое изображение 8x8.Это работает ... вроде, но получающиеся изображения деформированы и наклонены.
Это код, который я сейчас использую:
private static Bitmap CreateBinaryImage(Bitmap zero, Bitmap one, Bitmap source)
{
// store all results and their location here
var imageList = new List<KeyValuePair<Point, Bitmap>>();
// new width and height
int w = source.Width * zero.Width;
int h = source.Height * zero.Height;
// width and height of binary image
int hbin = zero.Height;
int wbin = zero.Width;
// image position indexer
int posX = 0;
int posY = 0;
// bitmap to draw on
var canvas = new Bitmap(w, h, source.PixelFormat);
unsafe
{
BitmapData lockBits = source.LockBits(
new Rectangle(0, 0, source.Width, source.Height),
ImageLockMode.ReadWrite,
source.PixelFormat);
try
{
// byte per pixel
int bpp = Bitmap.GetPixelFormatSize(source.PixelFormat) / 8;
int hip = lockBits.Height;
int wib = lockBits.Width;
// pointer to first pixel
byte* ptrPx = (byte*)lockBits.Scan0;
// length of stride
int bytes = Math.Abs(lockBits.Stride);
for (int y = 0; y < hip; y++)
{
// get pointer to current scanline
byte* scanLine = ptrPx + y * bytes;
// iterate through pixels
for (int x = 0; x < bytes; x += bpp)
{
// calculate average to determine if pixel will be 1 or 0
float avg = ((scanLine[x + 2] & 0xff) / 255f +
(scanLine[x + 1] & 0xff) / 255f +
(scanLine[x ] & 0xff) / 255f) / 3;
avg = Math.Min(1f, .35f + .65f * avg);
// set location and bitmap which will later be drawn
imageList.Add(new KeyValuePair<Point, Bitmap>(
new Point(posX, posY),
avg < 0.53f ? one : zero));
// increment or decrement the binary image location variables
posX += wbin;
if (posX > w)
{
posY += hbin;
posX = 0;
}
}
}
using (var g = Graphics.FromImage(canvas))
{
// draw images on canvas bitmap
for (int i = 0; i < imageList.Count; i++)
{
g.DrawImage(imageList[i].Value, imageList[i].Key);
}
}
}
finally
{
// release locked bits
if (source != null) {
source.UnlockBits(lockBits);
}
}
return canvas;
}
}
И результаты выглядят как this или это (исходное изображение слева и двоичное изображение справа)
Я просто не понимаю, что я делаю неправильно ...
Здесьявляется основным между прочим:
static void Main(string[] args)
{
var source = (Bitmap)Load.FromFile("c:\\dir\\...\\some_image_to_convert.jpeg");
var zero = (Bitmap)Load.FromFile("c:\\dir\\...\\bin_0_8px.png");
var one = (Bitmap)Load.FromFile("c:\\dir\\...\\bin_1_8px.png");
var binaryImage = CreateBinaryImage(zero, one, source);
binaryImage.Save("c:\\dir\\...\\desktop\\binaryImage_test.jpeg");
Console.Write("Done... Press any key to exit");
Console.ReadKey();
}