Создать изображение в формате JPEG из буферного массива - PullRequest
0 голосов
/ 03 сентября 2018

Я пытаюсь сохранить изображение в формате JPEG из буферного массива RGBA.
Я попробовал этот код

byte[] buffer = new byte[m_FrameProps.ImgSize];
Marshal.Copy(m_BM.BackBuffer, buffer, 0, m_FrameProps.ImgSize); //m_BM is WriteableBitmap
using (MemoryStream imgStream = new MemoryStream(buffer))
{
    using (System.Drawing.Image image = System.Drawing.Image.FromStream(imgStream))
    {
        image.Save(m_WorkingDir + "1", ImageFormat.Jpeg); 
    }
} 

Но я получаю ошибку во время выполнения: «Произошло необработанное исключение типа« System.ArgumentException »в System.Drawing.dll

Дополнительная информация: параметр недействителен. "

Я также пытался создать растровое изображение и затем использовать JpegBitmapEncoder

Bitmap bitmap;
using (var ms = new MemoryStream(buffer))
{
    bitmap = new Bitmap(ms);
} 

Но я получаю ту же ошибку.
Я думаю, это потому, что альфа.
Как я должен это делать? Нужно ли зацикливать значения и копировать без альфы?

1 Ответ

0 голосов
/ 06 сентября 2018

Невозможно построить изображение только из массива данных пикселей. При минимальном формате в пикселях также потребуются информация и размеры изображения. Это означает, что любая попытка создать растровое изображение непосредственно из массива ARGB с использованием потоков потерпит неудачу, оба метода Image.FromStream() и Bitmap() требуют, чтобы поток содержал некоторую информацию заголовка для построения изображения.

Тем не менее, учитывая, что вы, похоже, знаете размеры и формат пикселей изображения, которое хотите сохранить, вы можете использовать следующий метод:

public void SaveAsJpeg(int width, int height, byte[] argbData, int sourceStride, string path)
{
    using (Bitmap img = new Bitmap(width, height, PixelFormat.Format32bppPArgb))
    {
        BitmapData data = img.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, img.PixelFormat);
        for (int y = 0; y < height; y++)
        {
            Marshal.Copy(argbData, sourceStride * y, data.Scan0 + data.Stride * y, width * 4);
        }
        img.UnlockBits(data);
        img.Save(path, ImageFormat.Jpeg);
    }
}
...