画像からすべての白または透明のピクセルを削除して、実際の画像(トリミング)を残そうとしています。私はいくつかの解決策を試しましたが、どれもうまくいかないようです。何か提案がありますか、それとも画像トリミングコードを書くために夜を過ごすつもりですか?
6 に答える
したがって、実行したいのは、上、左端の非白/透明ピクセルと下、右端の非白/透明ピクセルを見つけることです。これらの2つの座標により、抽出できる長方形が得られます。
// 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);
}
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()
。これを行うには適切な方法です-StackOverflowにはたくさんの例があります。Width
Height
Bitmap
LockBits
WPFには、WriteableBitmapクラスがあります。これはあなたが探しているものですか?その場合は、http://blogs.msdn.com/b/jgalasyn/archive/2008/04/17/using-writeablebitmap-to-display-a-procedural-texture.aspxをご覧ください。
ピクセルごとのチェックでうまくいくはずです。各行をスキャンして上下から空の行を見つけ、各行をスキャンして左右の制約を見つけます(これは、行または列のいずれかを使用して1回のパスで実行できます)。制約が見つかったら、画像の一部を別のバッファにコピーします。
数千の.jpgファイルを約10分でバッチトリミングする方法を見つけましたが、コードでは実行しませんでした。Snag-ItEditorの変換機能を使用しました。これがあなたにとっての選択肢であるかどうか、一度このトリミングを行う必要があるか、またはあなたの必要性が継続しているのかはわかりませんが、ソフトウェアの価格はそれほど高くないので、これはまともな回避策だと思いました。(私はTechsmithで働いたり、代表したりしていません。)
ジョーイ
これに加えて、WPFを使用していて、画像の周囲に余分なスペースがある場合は、画像のプロパティを確認し、Stretchプロパティがfillに設定されていることを確認してください。これにより、画像の周囲のスペースがなくなりました。