Rank: Advanced Member
Groups: Administration
Joined: 1/31/2005(UTC) Posts: 458
Was thanked: 5 time(s) in 5 post(s)
|
Hi guys, Recently we have been asked how to implement auto-crop operation. I believe that code better than words in most cases, so here is simple sample. It is written in C# and has unsafe blocks, so you should have "Project Properties->Build->Allow unsafe code" option turned on. Usage: - Load RGB image (the sample doesn't support transparency or CMYK/indexed/grayscale images);
- Choose color which to treat as "empty space";
- Press "Find Margins" button.
The code inside is very straightforward. It iterates through the input picture along each side searching for any pixel which is not equal to the specified "margin color". The result should looks like on the screenshot below. Feel free to post your comments (or maybe, bugreports? ;)). Edited by moderator Monday, May 28, 2012 8:23:31 PM(UTC)
| Reason: Not specified File Attachment(s): Alex Kon attached the following image(s): |
|
|
|
|
Rank: Member
Groups: Member
Joined: 8/22/2006(UTC) Posts: 7
Thanks: 1 times
|
Hi, I have the same need, but my images are .png files with transparent background around the sides. Is there any way to find the margins and crop based on transparency? Thanks, Eddie
|
|
|
|
Rank: Advanced Member
Groups: Administration
Joined: 1/31/2005(UTC) Posts: 458
Was thanked: 5 time(s) in 5 post(s)
|
Hello Eddie, You can use the same code with minor changes. Instead of comparison with "emptyColor" you should check pixel's alpha channel in MarginsTracer class. For example, method which inspects image scanline should be changed in such way: Code:private static bool rowIsEmpty(BitmapData raster, int rowIndex, RgbColor emptyColor)
{
int w = raster.Width;
int j = 0;
unsafe
{
byte* pAlpha= (byte*)raster.Scan0.ToPointer() + rowIndex * raster.Stride + 3 /*skip 3 color channels to get alpha*/;
for (; j < w; j++)
{
if (*pAlpha> 0)
break;
pAlpha+= 4; //Shift to the next pixel in 32bppArgb.
}
}
return (j >= w);
}
columnIsEmpty() method should be modified in the same way. Also, do not forget to check that PixelFormat of source image is Format32bppArgb. Otherwise you can get memory access violation errors. Best regards, Alex Kon Edited by moderator Friday, July 8, 2011 6:04:50 PM(UTC)
| Reason: Not specified |
|
 1 user thanked Alex Kon for this useful post.
|
|
|
Rank: Member
Groups: Member
Joined: 8/22/2006(UTC) Posts: 7
Thanks: 1 times
|
I am really bad at C#. Can anyone convert this to VB?
|
|
|
|
Rank: Advanced Member
Groups: Administration
Joined: 12/19/2012(UTC) Posts: 164
Was thanked: 8 time(s) in 8 post(s)
|
Hello eddieharary, Unfortunately we do not have the VB.NET project. I've tried to google your problem and I found this topic: http://stackoverflow.com...-sharp-project-to-vb-net You can use some "C# to VB.NET" code converter. Best regards, Vitaly Kustov Aurigma Technical Support |
Best regards, Vitaly Kustov Aurigma Technical Support
|
|
|
|
Rank: Member
Groups: Member
Joined: 8/22/2006(UTC) Posts: 7
Thanks: 1 times
|
Hi Vitaly, I tried a few converters and after conversion I get errors. Maybe you can help with this: Dim pPixel As Byte* = CByte(raster.Scan0.ToPointer()) + rowIndex * raster.Stride Error: 'ToPointer' has a return type that is not supported or Parameter types that are not supported. Thanks, Eddie
|
|
|
|
Rank: Member
Groups: Member
Joined: 8/22/2006(UTC) Posts: 7
Thanks: 1 times
|
Hi Vitaly, It turns out pointers are not supported in VB.Net so there is no easy way to convert it. I was able to compile the C# as a Class Library and reference it in VB. The only problem is I tried making the same changes to columnIsEmpty() as Alex made for rowIsEmpty() but it isn't working. Could you post the correct code for columnIsEmpty() to scan the alpha channel instead of checking for a color match? Thanks, Eddie
|
|
|
|
Rank: Member
Groups: Member
Joined: 8/22/2006(UTC) Posts: 7
Thanks: 1 times
|
Ok I got it. Here is the code in case anyone else needs it: Code:
private static bool columnIsEmpty(BitmapData raster, int columnIndex, int start, int stop, RgbColor emptyColor)
{
int stride = raster.Stride;
int i = start;
unsafe
{
byte* pAlpha = (byte*)raster.Scan0.ToPointer() + (start * stride + columnIndex * 4) + 3 /*skip 3 color channels to get alpha*/;
for (; i <= stop; i++)
{
if (*pAlpha > 0)
break;
pAlpha += stride;
}
}
return (i > stop);
}
|
|
|
|
Rank: Advanced Member
Groups: Administration
Joined: 12/19/2012(UTC) Posts: 164
Was thanked: 8 time(s) in 8 post(s)
|
Hello eddieharary, Sorry for the long delayed. I had a holiday. Thanks a lot for your code snippet. Best regards, Vitaly Kustov Aurigma Technical Support |
Best regards, Vitaly Kustov Aurigma Technical Support
|
|
|
|
Rank: Newbie
Groups: Administration
Joined: 3/4/2014(UTC) Posts: 1
|
|
|
|
|
Rank: Advanced Member
Groups: Member, Administration, Moderator Joined: 7/28/2003(UTC) Posts: 1,659
Thanks: 5 times Was thanked: 76 time(s) in 74 post(s)
|
Currently it is possible to use the AutoCrop class. |
Best regards, Fedor Skvortsov
|
|
|
|
Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.