asp.net C# -裁剪透明/白色

fnatzsnv  于 2023-02-06  发布在  .NET
关注(0)|答案(6)|浏览(148)

我试图从一张图片中删除所有白色或透明像素,留下实际的图片(裁剪)。我尝试了一些解决方案,但似乎都不起作用。有什么建议吗?或者我打算花一晚上的时间编写图片裁剪代码?

pcrecxhr

pcrecxhr1#

所以你要做的就是找到最左上方的非白色/透明像素和最右下方的非白色/透明像素,这两个坐标会给予你一个矩形,然后你可以提取它。

// Load the bitmap
  Bitmap originalBitmap = Bitmap.FromFile("d:\\temp\\test.bmp") as Bitmap;

  // Find the min/max non-white/transparent pixels
  Point min = new Point(int.MaxValue, int.MaxValue);
  Point max = new Point(int.MinValue, int.MinValue);

  for (int x = 0; x < originalBitmap.Width; ++x)
  {
    for (int y = 0; y < originalBitmap.Height; ++y)
    {
      Color pixelColor = originalBitmap.GetPixel(x, y);
      if (!(pixelColor.R == 255 && pixelColor.G == 255 && pixelColor.B == 255)
        || pixelColor.A < 255)
      {
        if (x < min.X) min.X = x;
        if (y < min.Y) min.Y = y;

        if (x > max.X) max.X = x;
        if (y > max.Y) max.Y = y;
      }
    }
  }

  // Create a new bitmap from the crop rectangle
  Rectangle cropRectangle = new Rectangle(min.X, min.Y, max.X - min.X, max.Y - min.Y);
  Bitmap newBitmap = new Bitmap(cropRectangle.Width, cropRectangle.Height);
  using (Graphics g = Graphics.FromImage(newBitmap))
  {
    g.DrawImage(originalBitmap, 0, 0, cropRectangle, GraphicsUnit.Pixel);
  }
qnzebej0

qnzebej02#

public Bitmap CropBitmap(Bitmap original)
{
    // determine new left
    int newLeft = -1;
    for (int x = 0; x < original.Width; x++)
    {
        for (int y = 0; y < original.Height; y++)
        {
            Color color = original.GetPixel(x, y);
            if ((color.R != 255) || (color.G != 255) || (color.B != 255) || 
                (color.A != 0))
            {
                // this pixel is either not white or not fully transparent
                newLeft = x;
                break;
            }
        }
        if (newLeft != -1)
        {
            break;
        }

        // repeat logic for new right, top and bottom

    }

    Bitmap ret = new Bitmap(newRight - newLeft, newTop - newBottom);
    using (Graphics g = Graphics.FromImage(ret)
    {
        // copy from the original onto the new, using the new coordinates as
        // source coordinates for the original
        g.DrawImage(...);
    }

    return ret
}

请注意,这个函数非常慢。GetPixel()慢得令人难以置信,在循环中访问BitmapWidthHeight属性也很慢。LockBits是正确的方法-StackOverflow上有大量的示例。

xdyibdwo

xdyibdwo3#

逐像素检查应该可以做到。扫描每一行从顶部和底部找到空行,扫描每一行找到左右约束(这可以在一次通过行或列时完成)。当找到约束时-将图像的一部分复制到另一个缓冲区。

vohkndzv

vohkndzv4#

在WPF中,我们有一个WriteableBitmap类。这是您要查找的吗?如果是,请查看http://blogs.msdn.com/b/jgalasyn/archive/2008/04/17/using-writeablebitmap-to-display-a-procedural-texture.aspx

hi3rlvi2

hi3rlvi25#

我发现了一个方法,可以在大约10分钟内批量修剪几千个.jpg文件,但我没有用代码来做。我使用了Snag-It编辑器的转换功能。我不知道这是否适合你,如果你需要做一次修剪,或者你的需要是持续的,但对于软件的价格,这不是一个整体很多,我认为这是一个不错的变通办法。(我不为TechSmith工作,也不代表TechSmith。)
乔伊

nvbavucw

nvbavucw6#

此外,如果您在WPF中并且图像周围有多余的空间,请检查图像的属性并确保将***Stretch***属性设置为fill。这将消除图像周围的空间。
Screen shot of the property in WPF

相关问题