Reputation: 191
When converting Image to 8bpp there are vertical lines in the resulting 8bpp Image. Why does this occur?
static Bitmap To8bpp(Bitmap original)
{
int width = original.Width;
int height = original.Height;
Bitmap result = new Bitmap(width, height);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Color color = original.GetPixel(x, y);
result.SetPixel(x, y, color);
}
}
Rectangle rectangle = new Rectangle(0, 0, width, height);
PixelFormat pixelFormat = PixelFormat.Format8bppIndexed;
BitmapData bitmapData = result.LockBits(rectangle, ImageLockMode.ReadOnly, result.PixelFormat);
Bitmap bitmap = new Bitmap(width * 4, height, bitmapData.Stride, pixelFormat, bitmapData.Scan0);
result.UnlockBits(bitmapData);
return bitmap;
}
Upvotes: 1
Views: 113
Reputation: 191
static Bitmap Get8bpp(Bitmap original)
{
if (original == null) return null;
if (original.PixelFormat == PixelFormat.Format8bppIndexed)
return (Bitmap)original.Clone();
Rectangle rectangle = new Rectangle(0, 0, original.Width, original.Height);
Bitmap bitmap = original.Clone(rectangle, PixelFormat.Format32bppRgb);
PixelFormat pixelFormat = PixelFormat.Format8bppIndexed;
int w = bitmap.Width,
h = bitmap.Height,
ic = 0,
oc = 0,
bmpStride,
outputStride,
bytesPerPixel;
PixelFormat pfIn = bitmap.PixelFormat;
Bitmap output = new Bitmap(w, h, pixelFormat);
BitmapData bmpData, outputData;
switch (pfIn)
{
case PixelFormat.Format24bppRgb: bytesPerPixel = 3; break;
case PixelFormat.Format32bppArgb: bytesPerPixel = 4; break;
case PixelFormat.Format32bppRgb: bytesPerPixel = 4; break;
default: throw new InvalidOperationException("Image format not supported");
}
bmpData = bitmap.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, pfIn);
outputData = output.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, pixelFormat);
bmpStride = bmpData.Stride;
outputStride = outputData.Stride;
unsafe
{
byte* bmpPtr = (byte*)bmpData.Scan0.ToPointer(),
outputPtr = (byte*)outputData.Scan0.ToPointer();
if (bytesPerPixel == 3)
{
Set3BytesPerPixel(w, h, ref ic, ref oc, bmpStride, outputStride, bmpPtr, outputPtr);
}
else
{
Set4BytesPerPixel(w, h, ref ic, ref oc, bmpStride, outputStride, bmpPtr, outputPtr);
}
}
bitmap.UnlockBits(bmpData);
output.UnlockBits(outputData);
return output;
}
private static unsafe void Set3BytesPerPixel(int w, int h, ref int ic, ref int oc, int bmpStride, int outputStride, byte* bmpPtr, byte* outputPtr)
{
int r;
for (r = 0; r < h; r++)
for (ic = oc = 0; oc < w; ic += 3, ++oc)
outputPtr[r * outputStride + oc] = (byte)(int)
(
.299 * bmpPtr[r * bmpStride + ic] +
.587 * bmpPtr[r * bmpStride + ic + 1] +
.114 * bmpPtr[r * bmpStride + ic + 2]
);
}
private static unsafe void Set4BytesPerPixel(int w, int h, ref int ic, ref int oc, int bmpStride, int outputStride, byte* bmpPtr, byte* outputPtr)
{
int r;
for (r = 0; r < h; r++)
for (ic = oc = 0; oc < w; ic += 4, ++oc)
outputPtr[r * outputStride + oc] = (byte)(int)
((bmpPtr[r * bmpStride + ic] / 255.0f) *
(.299 * bmpPtr[r * bmpStride + ic + 1] +
.587 * bmpPtr[r * bmpStride + ic + 2] +
.114 * bmpPtr[r * bmpStride + ic + 3]
)
);
}
Upvotes: 1