代码之家  ›  专栏  ›  技术社区  ›  A.Pissicat

添加边框到索引的图像1 bpp

  •  1
  • A.Pissicat  · 技术社区  · 6 年前

    我想给图像添加边框。

    为了实现这一点,我想用板条箱装一个新的空图像,其大小等于旧大小+边框大小,在中间复制旧图像并绘制边框:

    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而不是图形,因为我无法从format1bpindexed创建图形元素。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Perfect28    6 年前

    弗斯特 Marshal.Copy 期待着 byte [] 数组,这就是它不编译的原因。

    其次,您不需要将低字节操作作为 Graphics 处理此作业所需的所有操作(这是 真正的 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);
            }
        }
    

    这个想法很简单:

    • 使用边框颜色的背景创建新的结果位图
    • 在正确的位置绘制内部原始图像( 边界尺寸 , 边界尺寸 )
    • 使用原始PixelFormat克隆最终结果
        2
  •  0
  •   Albert Alberto    6 年前

    我用了系统,绘图,得到了结果。希望这就是你想要的。

    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;
        }
    
    推荐文章