Добавить границу к изображениям 1 bpp проиндексирован - PullRequest
0 голосов
/ 11 февраля 2019

Я хочу добавить рамку к изображению.

Для этого я хочу создать новое пустое изображение с размером, равным старому размеру + размеру границы, скопировать старое изображение в центр и нарисовать границу:

enter image description here

Существует метод, который я написал:

private Bitmap addBorderToImage(Image image, int borderSize)
{
    Bitmap bmpTmp = new Bitmap(image);

    Bitmap bmp = new Bitmap(bmpTmp.Width + 2 * borderSize,
                            bmpTmp.Height + 2 * borderSize,
                            bmpTmp.PixelFormat);

    BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
    BitmapData dataTmp = bmpTmp.LockBits(new Rectangle(0, 0, bmpTmp.Width, bmpTmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed);
    // Copy the bytes from the image into a byte array
    for (int y = 0; y < bmpTmp.Height; y++)
    {
        System.Runtime.InteropServices.Marshal.Copy(dataTmp.Scan0, y * data.Stride, (IntPtr)((long)data.Scan0 + data.Stride * y + borderSize), y * data.Stride);
    }
    bmp.UnlockBits(data);
    bmpTmp.UnlockBits(data);

    using (Graphics g = Graphics.FromImage(bmp))
    {
        g.DrawRectangle(new Pen(Brushes.Green, borderSize * 2), new Rectangle(0, 0, bmp.Width, bmp.Height));
    }
    return bmp;
}

Но я не могу сделать правильную копию.У меня ошибка:

Аргумент 1: невозможно преобразовать из 'System.IntPtr' в 'byte []'

Как мне сделать Marshal.Copy?

Редактировать: Я использую Marshall.copy вместо графики, потому что не могу создать графический элемент из Format1bppIndexed.

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Я использовал System.Drawing и получил результаты.Надеюсь, это то, что вы искали.

private Bitmap AddBorder(Image original_image, int border_size, Color border_color)
    {
        Size originalSize = new Size(original_image.Width + border_size, original_image.Height + border_size);
        Bitmap bmp = new Bitmap(originalSize.Width, originalSize.Height);
        Rectangle rec = new Rectangle(new Point(0, 0), originalSize);
        Pen pen = new Pen(border_color, border_size);
        Graphics g = Graphics.FromImage(bmp);
        g.DrawRectangle(pen, rec);
        rec.Inflate(-border_size /2, -border_size /2);
        g.DrawImage(original_image, rec);
        return bmp;
    }
0 голосов
/ 11 февраля 2019

Первый Marshal.Copy ожидает массив byte [], поэтому он не компилируется.

Во-вторых, вам не нужно манипулировать младшим байтом, поскольку Graphics обрабатывает все операции, которые вам нужны дляэто задание (это подлинная XY проблема ).

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

Как насчет следующего:

    private static Bitmap AddBorderToImage(Image image, int borderSize)
    {
        using (Bitmap bmp = new Bitmap(image.Width + 2 * borderSize,
            image.Height + 2 * borderSize))
        {
            using (Graphics destGraph = Graphics.FromImage(bmp))
            {
                destGraph.FillRectangle(Brushes.Green, new Rectangle(new Point(0, 0), bmp.Size));
                destGraph.DrawImage(image, new Point(borderSize, borderSize));
            }

            return bmp.Clone(new Rectangle(0, 0, bmp.Width, bmp.Height), image.PixelFormat);
        }
    }

Идея простакак это:

  • Создание нового растрового изображения с фоном цвета границы
  • Нарисуйте внутреннее исходное изображение в правильном месте ( borderSize , borderSize ).
  • Клонировать конечный результат с оригинальным PixelFormat
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...