简体   繁体   English

为图像添加边框 1 bpp 索引

[英]Add border to images 1 bpp indexed

I want to add a border to an Image.我想为图像添加边框。

To achieve that, I want to crate a new empty image with size equal to old size + border size, copy old image on center and draw border :为此,我想创建一个大小等于旧大小 + 边框大小的新空图像,在中心复制旧图像并绘制边框:

在此处输入图片说明

There is the method I wrote :有我写的方法:

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;
}

But I'm unable to do a correct copy.但我无法做一个正确的副本。 I have error :我有错误:

Argument 1: cannot convert from 'System.IntPtr' to 'byte[]'参数 1:无法从“System.IntPtr”转换为“byte[]”

How should I do the Marshal.Copy ?我应该怎么做Marshal.Copy

Edit: I use Marshall.copy instead of graphics cause I can't create graphics element from Format1bppIndexed.编辑:我使用 Marshall.copy 而不是图形,因为我无法从 Format1bppIndexed 创建图形元素。

First Marshal.Copy is expecting a byte [] array that's why it doesn't compile.首先Marshal.Copy需要一个byte []数组,这就是它无法编译的原因。

Second, you don't need to have low byte manipulation as Graphics handles all operation you need for this job (this is an authentic XY problem ).其次,您不需要进行低字节操作,因为Graphics处理这项工作所需的所有操作(这是一个真正的XY 问题)。

Last, there are many undisposed object in your original code which will leads you to memory leaks.最后,您的原始代码中有许多未处理的对象会导致内存泄漏。

What about the following :以下情况如何:

    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);
        }
    }

The idea is as simple as this:这个想法很简单:

  • Create a new result bitmap with the background of border's color以边框颜色为背景创建一个新的结果位图
  • Draw the inner original image at the correct place ( borderSize , borderSize ).在正确的位置( borderSizeborderSize )绘制内部原始图像。
  • Clone the final result with original PixelFormat使用原始 PixelFormat 克隆最终结果

I used System.Drawing and got the results.我使用了 System.Drawing 并得到了结果。 Hope this is what you were looking for.希望这就是你要找的。

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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM