Как я могу сохранить изображение как файл растрового изображения? - PullRequest
0 голосов
/ 23 октября 2018

Я сделал функцию автоматического определения порога изображения и хочу сохранить ее как файл растрового изображения.

Однако, когда я использую функцию Bitmap.Save C # GDI + , хотя я установил ImageFormat как BMP, он всегда является файлом цветного изображения RGB, но не файлом растрового изображения.

Я должен сохранить его как файл растрового изображения, поскольку принтер может только прочитать файл растрового изображения.

Может быть, вы спросите меня, что такое файл растрового изображения.Я не специалист по обработке изображений и извиняюсь за это вряд ли могу объяснить четко.Но я могу привести пример: в Photoshop есть несколько цветовых режимов, таких как режим RGB / режим CMYK / режим индекса / режим градаций серого / режим растрового изображения, я хочу сохранить изображение в виде растрового изображения в C #.

Вот что Adobe объясняет о растровом режиме на своем веб-сайте :

В растровом режиме используется одно из двух значений цвета (черный или белый) для представленияпикселей в изображении.Изображения в растровом режиме называются растровыми 1-битными изображениями, потому что они имеют битовую глубину 1.

Я гуглил, но ничего не нашел по этому поводу.Как я могу сделать это в C #?Спасибо.

Вот мой код:

Thread T = new Thread(() => {
    Bitmap processedBitmap = new Bitmap(@"G:\\0001.jpg");

    BitmapData bitmapData = processedBitmap.LockBits(new Rectangle(0, 0, processedBitmap.Width, processedBitmap.Height), ImageLockMode.ReadWrite, processedBitmap.PixelFormat);

    int bytesPerPixel = Bitmap.GetPixelFormatSize(processedBitmap.PixelFormat) / 8;
    int byteCount = bitmapData.Stride * processedBitmap.Height;
    byte[] pixels = new byte[byteCount];
    IntPtr ptrFirstPixel = bitmapData.Scan0;
    Marshal.Copy(ptrFirstPixel, pixels, 0, pixels.Length);
    int heightInPixels = bitmapData.Height;
    int widthInBytes = bitmapData.Width * bytesPerPixel;

    for (int y = 0; y < heightInPixels; y++)
    {
        int currentLine = y * bitmapData.Stride;
        for (int x = 0; x < widthInBytes; x = x + bytesPerPixel)
        {
            int oldBlue = pixels[currentLine + x];
            int oldGreen = pixels[currentLine + x + 1];
            int oldRed = pixels[currentLine + x + 2];

            double averageColor = (oldBlue + oldGreen + oldRed) / 3;

            int NewC;
            if (averageColor > 200)
            {
                NewC = 255;
            }
            else
            {
                NewC = 0;
            }
            // calculate new pixel value
            pixels[currentLine + x] = (byte)NewC;
            pixels[currentLine + x + 1] = (byte)NewC;
            pixels[currentLine + x + 2] = (byte)NewC;
        }
    }

    // copy modified bytes back
    Marshal.Copy(pixels, 0, ptrFirstPixel, pixels.Length);
    processedBitmap.UnlockBits(bitmapData);

    processedBitmap.Save("G:\\aaa.bmp", ImageFormat.Bmp);
    MessageBox.Show("Sucess!");
});
T.Start();

Ответы [ 3 ]

0 голосов
/ 23 октября 2018

Я полагаю, что OP ссылается на последний тип изображения в этой Adobe Link Битовая карта - это просто контейнер для данных, формат сохраняемых данных определяется настройкой PixelFormat.Как видно, режим «Adobe» для растровых изображений представляет собой режим двухцветного формата и соответствует PixelFormat.Format1bppIndexed в растровом изображении C #.

У вас есть несколько конструкторов для растровых изображений, которые имеют PixelFormat какпараметр.

1.

public Bitmap (int width, int height, System.Drawing.Imaging.PixelFormat format);

2.

public Bitmap (int width, int height, int stride, System.Drawing.Imaging.PixelFormat format, IntPtr scan0);
0 голосов
/ 23 октября 2018

С вашим исходным изображением у вас есть 24-битное изображение.Когда вы выполняете усреднение цвета, вы записываете обратно в буфер изображения со следующим кодом:

pixels[currentLine + x] = (byte)NewC;
pixels[currentLine + x + 1] = (byte)NewC;
pixels[currentLine + x + 2] = (byte)NewC;

Вы снова записываете 24 бита.
Например, если ваши исходные значения дляRGB были (202, 203, 249), затем NewC был бы 218, а затем вы устанавливаете пороговое значение обратно на 255, поэтому вы записываете обратно (255,255,255), которое по-прежнему является значением RGB, оно только для белого.Затем вы сохраняете это изображение, используя

processedBitmap.Save("G:\\aaa.bmp", ImageFormat.Bmp);

. Класс ImageFormat просто устанавливает тип изображения, такой как jpeg, png и т. Д. И, как вы обнаружили, у вас по-прежнему выводится 24-битное изображение.

Итак, вы хотите сохранить изображение в виде чистого черно-белого изображения размером 1 бит на пиксель.Для этого вам нужно указать PixelFormat изображения, которое вы сохраняете, и, в частности, вы хотите PixelFormat Format1bppIndexed.

Если вы вместо этого измените соответствующий бит вашего кода на:

...
Marshal.Copy(pixels, 0, ptrFirstPixel, pixels.Length);
processedBitmap.UnlockBits(bitmapData);

Bitmap clone = processedBitmap.Clone(new Rectangle(0, 0, processedBitmap.Width, processedBitmap.Height), PixelFormat.Format1bppIndexed);
clone.Save("G:\\aaa.bmp", ImageFormat.Bmp);

MessageBox.Show("Success!");

Теперь ваш выходной клон будет изображением размером 1 бит на дюйм.

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

Bitmap processedBitmap = new Bitmap(@"G:\0001.jpg");
Bitmap clone = processedBitmap.Clone(new Rectangle(0, 0, processedBitmap.Width, processedBitmap.Height), PixelFormat.Format1bppIndexed);
clone.Save("G:\\aaa.bmp", ImageFormat.Bmp);
MessageBox.Show("Success!");

Имейте в виду, что вывод немного отличается.Вот несколько тестовых примеров вывода.

Это мое входное изображение:

Вывод изображения с вашим пороговым кодом:

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

0 голосов
/ 23 октября 2018

Чтобы сохранить объект BMP в файл, все, что вам нужно сделать это:

bmp.Save("c:\\Path\\To\\File\\image.bmp, ImageFormat.Bmp);

Вы делаете что-нибудь еще?

...