I searched for a simple code that preform "TRIMMING" to an image.
By "trimming" i mean, that if i have a LARGE image that contains information (painting/drawing...) only in small part of the image and all other is white-space (WHITE or BLACK pixels).
I needed to remove such whitespace and also to decrease image size.
Following three code examples:
Code #1 - Gets the NON-WHITE-SPACE bounds of an image
Code #2 - Draw rectangle around the NON-WHITE-SPACE
Code #3 - Trim Image whitespaces
I hope it will be helpful for you.
this code if fast and easy to use.
By "trimming" i mean, that if i have a LARGE image that contains information (painting/drawing...) only in small part of the image and all other is white-space (WHITE or BLACK pixels).
I needed to remove such whitespace and also to decrease image size.
Following three code examples:
Code #1 - Gets the NON-WHITE-SPACE bounds of an image
private Rectangle GetImageNonWhiteSpaceBounds(Bitmap p_img, bool p_isBlackWhitespace)
{
Rectangle rect = new Rectangle();
unsafe
{
BitmapData bdActual = null;
try
{
int width = p_img.Width;
int height = p_img.Height;
bdActual = p_img.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
Int32 i;
Int32 pSize = 3;
Byte whiteTrashold = (Byte)240;
Byte blackTrashold = (Byte)10;
Byte* sourceRow;
Int32 minX = width;
Int32 maxX = 0;
Int32 minY = height;
Int32 maxY = 0;
bool isWhitepace;
for (Int32 _y = 0; _y < height; ++_y) { sourceRow = (Byte*)bdActual.Scan0 + (_y * bdActual.Stride); for (Int32 _x = 0; _x < width; ++_x) { i = _x * pSize; isWhitepace = (p_isBlackWhitespace && sourceRow[i] <= blackTrashold && sourceRow[i + 1] <= blackTrashold && sourceRow[i + 2] <= blackTrashold) || (!p_isBlackWhitespace && sourceRow[i] >= whiteTrashold && sourceRow[i + 1] >= whiteTrashold && sourceRow[i + 2] >= whiteTrashold);
if (isWhitepace == false)
{
// NO whitespace!!!
minX = Math.Min(_x, minX);
maxX = Math.Max(_x, maxX);
minY = Math.Min(_y, minY);
maxY = Math.Max(_y, maxY);
}
}
}
rect.X = minX;
rect.Y = minY;
rect.Width = maxX - minX;
rect.Height = maxY - minY;
}
finally
{
if (bdActual != null)
{
p_img.UnlockBits(bdActual);
}
}
}
return rect;
}
{
Rectangle rect = new Rectangle();
unsafe
{
BitmapData bdActual = null;
try
{
int width = p_img.Width;
int height = p_img.Height;
bdActual = p_img.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
Int32 i;
Int32 pSize = 3;
Byte whiteTrashold = (Byte)240;
Byte blackTrashold = (Byte)10;
Byte* sourceRow;
Int32 minX = width;
Int32 maxX = 0;
Int32 minY = height;
Int32 maxY = 0;
bool isWhitepace;
for (Int32 _y = 0; _y < height; ++_y) { sourceRow = (Byte*)bdActual.Scan0 + (_y * bdActual.Stride); for (Int32 _x = 0; _x < width; ++_x) { i = _x * pSize; isWhitepace = (p_isBlackWhitespace && sourceRow[i] <= blackTrashold && sourceRow[i + 1] <= blackTrashold && sourceRow[i + 2] <= blackTrashold) || (!p_isBlackWhitespace && sourceRow[i] >= whiteTrashold && sourceRow[i + 1] >= whiteTrashold && sourceRow[i + 2] >= whiteTrashold);
if (isWhitepace == false)
{
// NO whitespace!!!
minX = Math.Min(_x, minX);
maxX = Math.Max(_x, maxX);
minY = Math.Min(_y, minY);
maxY = Math.Max(_y, maxY);
}
}
}
rect.X = minX;
rect.Y = minY;
rect.Width = maxX - minX;
rect.Height = maxY - minY;
}
finally
{
if (bdActual != null)
{
p_img.UnlockBits(bdActual);
}
}
}
return rect;
}
Code #2 - Draw rectangle around the NON-WHITE-SPACE
private void DrawNonWhiteSpaceRectangle(Bitmap p_img, bool p_isBlackWhitespace, Color p_color)
{
unsafe
{
BitmapData bdActual = null;
try
{
int width = p_img.Width;
int height = p_img.Height;
bdActual = p_img.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
Int32 i;
Int32 pSize = 3;
Byte whiteTrashold = (Byte)240;
Byte blackTrashold = (Byte)10;
Byte* sourceRow;
Int32 minX = width;
Int32 maxX = 0;
Int32 minY = height;
Int32 maxY = 0;
bool isWhitepace;
for (Int32 _y = 0; _y < height; ++_y) { sourceRow = (Byte*)bdActual.Scan0 + (_y * bdActual.Stride); for (Int32 _x = 0; _x < width; ++_x) { i = _x * pSize; isWhitepace = (p_isBlackWhitespace && sourceRow[i] <= blackTrashold && sourceRow[i + 1] <= blackTrashold && sourceRow[i + 2] <= blackTrashold) || (!p_isBlackWhitespace && sourceRow[i] >= whiteTrashold && sourceRow[i + 1] >= whiteTrashold && sourceRow[i + 2] >= whiteTrashold);
if (isWhitepace == false)
{
// NO whitespace!!!
minX = Math.Min(_x, minX);
maxX = Math.Max(_x, maxX);
minY = Math.Min(_y, minY);
maxY = Math.Max(_y, maxY);
}
}
}
// draw rectagle:
for (Int32 _y = minY; _y <= maxY; ++_y) { sourceRow = (Byte*)bdActual.Scan0 + (_y * bdActual.Stride); i = minX * pSize; sourceRow[i] = (Byte)p_color.R; sourceRow[i + 1] = (Byte)p_color.G; sourceRow[i + 2] = (Byte)p_color.B; i = maxX * pSize; sourceRow[i] = (Byte)p_color.R; sourceRow[i + 1] = (Byte)p_color.G; sourceRow[i + 2] = (Byte)p_color.B; } Byte* sourceRowX1 = (Byte*)bdActual.Scan0 + (minY * bdActual.Stride); Byte* sourceRowX2 = (Byte*)bdActual.Scan0 + (maxY * bdActual.Stride); for (Int32 _x = minX; _x <= maxX; ++_x) { i = _x * pSize; sourceRowX1[i] = (Byte)p_color.R; sourceRowX1[i + 1] = (Byte)p_color.G; sourceRowX1[i + 2] = (Byte)p_color.B; sourceRowX2[i] = (Byte)p_color.R; sourceRowX2[i + 1] = (Byte)p_color.G; sourceRowX2[i + 2] = (Byte)p_color.B; } } finally { if (bdActual != null) { p_img.UnlockBits(bdActual); } } } }
{
unsafe
{
BitmapData bdActual = null;
try
{
int width = p_img.Width;
int height = p_img.Height;
bdActual = p_img.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
Int32 i;
Int32 pSize = 3;
Byte whiteTrashold = (Byte)240;
Byte blackTrashold = (Byte)10;
Byte* sourceRow;
Int32 minX = width;
Int32 maxX = 0;
Int32 minY = height;
Int32 maxY = 0;
bool isWhitepace;
for (Int32 _y = 0; _y < height; ++_y) { sourceRow = (Byte*)bdActual.Scan0 + (_y * bdActual.Stride); for (Int32 _x = 0; _x < width; ++_x) { i = _x * pSize; isWhitepace = (p_isBlackWhitespace && sourceRow[i] <= blackTrashold && sourceRow[i + 1] <= blackTrashold && sourceRow[i + 2] <= blackTrashold) || (!p_isBlackWhitespace && sourceRow[i] >= whiteTrashold && sourceRow[i + 1] >= whiteTrashold && sourceRow[i + 2] >= whiteTrashold);
if (isWhitepace == false)
{
// NO whitespace!!!
minX = Math.Min(_x, minX);
maxX = Math.Max(_x, maxX);
minY = Math.Min(_y, minY);
maxY = Math.Max(_y, maxY);
}
}
}
// draw rectagle:
for (Int32 _y = minY; _y <= maxY; ++_y) { sourceRow = (Byte*)bdActual.Scan0 + (_y * bdActual.Stride); i = minX * pSize; sourceRow[i] = (Byte)p_color.R; sourceRow[i + 1] = (Byte)p_color.G; sourceRow[i + 2] = (Byte)p_color.B; i = maxX * pSize; sourceRow[i] = (Byte)p_color.R; sourceRow[i + 1] = (Byte)p_color.G; sourceRow[i + 2] = (Byte)p_color.B; } Byte* sourceRowX1 = (Byte*)bdActual.Scan0 + (minY * bdActual.Stride); Byte* sourceRowX2 = (Byte*)bdActual.Scan0 + (maxY * bdActual.Stride); for (Int32 _x = minX; _x <= maxX; ++_x) { i = _x * pSize; sourceRowX1[i] = (Byte)p_color.R; sourceRowX1[i + 1] = (Byte)p_color.G; sourceRowX1[i + 2] = (Byte)p_color.B; sourceRowX2[i] = (Byte)p_color.R; sourceRowX2[i + 1] = (Byte)p_color.G; sourceRowX2[i + 2] = (Byte)p_color.B; } } finally { if (bdActual != null) { p_img.UnlockBits(bdActual); } } } }
Code #3 - Trim Image whitespaces
private Bitmap CropImageWhitespaces(Bitmap p_img, bool p_isBlackWhitespace)
{
Rectangle rect = new Rectangle();
unsafe
{
BitmapData bdActual = null;
try
{
int width = p_img.Width;
int height = p_img.Height;
bdActual = p_img.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
Int32 i;
Int32 pSize = 3;
Byte whiteTrashold = (Byte)240;
Byte blackTrashold = (Byte)10;
Byte* sourceRow;
Int32 minX = width;
Int32 maxX = 0;
Int32 minY = height;
Int32 maxY = 0;
bool isWhitepace;
for (Int32 _y = 0; _y < height; ++_y) { sourceRow = (Byte*)bdActual.Scan0 + (_y * bdActual.Stride); for (Int32 _x = 0; _x < width; ++_x) { i = _x * pSize; isWhitepace = (p_isBlackWhitespace && sourceRow[i] <= blackTrashold && sourceRow[i + 1] <= blackTrashold && sourceRow[i + 2] <= blackTrashold) || (!p_isBlackWhitespace && sourceRow[i] >= whiteTrashold && sourceRow[i + 1] >= whiteTrashold && sourceRow[i + 2] >= whiteTrashold);
if (isWhitepace == false)
{
// NO whitespace!!!
minX = Math.Min(_x, minX);
maxX = Math.Max(_x, maxX);
minY = Math.Min(_y, minY);
maxY = Math.Max(_y, maxY);
}
}
}
rect.X = minX;
rect.Y = minY;
rect.Width = maxX - minX;
rect.Height = maxY - minY;
}
finally
{
if (bdActual != null)
{
p_img.UnlockBits(bdActual);
}
}
}
return p_img.Clone(rect, p_img.PixelFormat);
}
{
Rectangle rect = new Rectangle();
unsafe
{
BitmapData bdActual = null;
try
{
int width = p_img.Width;
int height = p_img.Height;
bdActual = p_img.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
Int32 i;
Int32 pSize = 3;
Byte whiteTrashold = (Byte)240;
Byte blackTrashold = (Byte)10;
Byte* sourceRow;
Int32 minX = width;
Int32 maxX = 0;
Int32 minY = height;
Int32 maxY = 0;
bool isWhitepace;
for (Int32 _y = 0; _y < height; ++_y) { sourceRow = (Byte*)bdActual.Scan0 + (_y * bdActual.Stride); for (Int32 _x = 0; _x < width; ++_x) { i = _x * pSize; isWhitepace = (p_isBlackWhitespace && sourceRow[i] <= blackTrashold && sourceRow[i + 1] <= blackTrashold && sourceRow[i + 2] <= blackTrashold) || (!p_isBlackWhitespace && sourceRow[i] >= whiteTrashold && sourceRow[i + 1] >= whiteTrashold && sourceRow[i + 2] >= whiteTrashold);
if (isWhitepace == false)
{
// NO whitespace!!!
minX = Math.Min(_x, minX);
maxX = Math.Max(_x, maxX);
minY = Math.Min(_y, minY);
maxY = Math.Max(_y, maxY);
}
}
}
rect.X = minX;
rect.Y = minY;
rect.Width = maxX - minX;
rect.Height = maxY - minY;
}
finally
{
if (bdActual != null)
{
p_img.UnlockBits(bdActual);
}
}
}
return p_img.Clone(rect, p_img.PixelFormat);
}
I hope it will be helpful for you.
this code if fast and easy to use.
No comments:
Post a Comment