Я пытаюсь создать Bitmap из массива байтов, используя этот код:
var b = new Bitmap(pervoe, vtoroe, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
ColorPalette ncp = b.Palette;
for (int i = 0; i < 256; i++)
ncp.Entries[i] = System.Drawing.Color.FromArgb(255, i, i, i);
b.Palette = ncp;
var BoundsRect = new Rectangle(0, 0, Width, Height);
BitmapData bmpData = b.LockBits(BoundsRect,ImageLockMode.WriteOnly,b.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = (bmpData.Stride)*(b.Height);
var rgbValues = new byte[bytes];
// filling values
Marshal.Copy(rgbValues, 0, ptr, bytes);
b.UnlockBits(bmpData);
return b;
проблема в том, что когда я получаю выходное изображение, каждая строка, начиная с первой, сдвигается вправо, поэтому все изображение не выглядит правильным. Проблема не в rgbValues - я пытался использовать его с методом setPixel, и он отлично работает. Любая помощь с классом маршала или что я делаю, чтобы предотвратить это изменение?
Код, который вы показываете, выглядит отлично и должен работать по назначению. Проблема, скорее всего, связана с тем, как вы внедрили //filling values
. Я предполагаю, что ширина вашего изображения такова, что bmpData.Stride != b.Width
(и, следовательно, bytes != Width * Height
), но вы не учитываете его и заполняете первые байты Width * Height
массива rgbValues
.
Для целей оптимизации реализация Bitmap
может выбрать добавление байтов заполнения каждой строки данных изображения, которые фактически не являются частью изображения. Если это так, вы должны учитывать это и записывать свои данные изображения в первые байты Width
каждой строки, где каждая строка начинается с индекса rowIndex * BitmapData.Stride
.
Таким образом, вы должны заполнить свой буфер по строкам:
for (int row = 0; row < b.Height; ++row)
{
int rowStart = row * bmpData.Stride;
for (int column = 0; column < b.Width; ++column)
{
rgbValues[rowStart + column] = GetColorForPixel(column, row);
}
}