在索引为1 bpp的图像上添加边框

时间:2019-02-11 10:59:51

标签: c# image

我想在图像上添加边框。

要实现这一点,我想创建一个新的空白图片,其大小等于旧大小+边框大小,将旧图片复制到中心并绘制边框:

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 :(得分:1)

第一个Marshal.Copy期望有一个byte []数组,这就是为什么它不能编译的原因。

第二,您不需要进行低字节操作,因为Graphics处理了此作业所需的所有操作(这是 authentic XY problem)。

最后,原始代码中有许多未处理的对象,这将导致您内存泄漏。

以下内容:

    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复制最终结果

答案 1 :(得分:0)

我使用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;
    }