I have an application that scan Images from scanner but some scanners put a black border around the saved image.
How can I remove that black border?
Thanks so much for your participation.
I’ve had good luck in the past process images using the Magick.NET library. It’s available on Codeplex or you can install it using NuGet in Visual Studio. Documentation for the library is a little sparse, but it’s served me well in the past.
Depending upon the exact nature of the images you’re dealing with, you might be able to do something as simple as crop off the edges where the border is and then add a white (or whatever color; I just assumed that you were scanning text documents or something) border to bring the image back up to a standardized size. If having a standardized size doesn’t matter, then of course you can just leave the image cropped. If that sounds like a viable solution, here’s some code that should accomplish what you need:
using (MagickImage image = new MagickImage(#"path_to_original"))
{
int width = image.Width, height = image.Height;
image.Crop(width - 800, height - 800);
//if the image needs to be brought back up to a standarized size
image.BorderColor = new ColorRGB(System.Drawing.Color.White);
image.Border(100, 100);
image.Write(#"path_to_cropped_image_with_no_more_black_border_around_it");
}
You will, of course need to add your own values for just how much width you need to crop off/add back in.
Related
This is a C# winforms question.
The process I am trying to achieve is the following:
Using AxAcroPDFLib I'm loading a pdf file to the form
I want the user to be able to specify a square on that PDF and create a bmp from it
That bmp will then be loaded to a OCR to become text
What is my issue:
Step 1 and 3 are easy to do, the problem is how to allow the user to draw a square on top of the AxAcroPDFLib for a screenshot.
I already got different ways to draw squares on native winform components, but AxAcroPDFLib does not support mouse down, up, move, etc and paint events.
There is the option to convert the PDF to bitmap and display it on a picturebox and deal with events for drawing the square. Problem with that approach is that my PDF's are usually more than two pages, and I would like to avoid the conversion pdf to bmp due to changes to image quality that will impact on OCR.
I came to think that maybe something that works as the windows snippingtool would do the the job. My application would get the screenshot, temporarily save the image on disk (must be a file for OCR), I would then pass it to the OCR and done. Hard part, I could not think on how to take the screenshot of part of the PDF.
Do anyone here have any suggestion to different components or workarounds to deal with the requirement above? I am using Adobe just because it is simple, but maybe there are other components better suited to handle my requirements? I googled but haven't found any free ones, trying to avoid paid options.
Thanks
At some point in this process, the PDF is going to have to be rasterized in order to be passed to the OCR, so I don't totally understand your objection to converting it to a bitmap. If you're okay with Snipping Tool's behavior, then you must be OK with the quality of the PDF control's PDF->screen rasterization. If that resolution is acceptable, why not just capture the control's content to a Bitmap and let the user draw the selection marquee over that Bitmap?
Here is code I'm using to capture a control's contents to a Bitmap in Windows Forms. One caveat is that this is really a screen capture, so any windows or controls that overlap the control's visible area will be captured in the image.
using (Bitmap b = new Bitmap(width, height))
{
using (Graphics g = Graphics.FromImage(b))
{
Point p1 = myControl.PointToScreen(new Point(0, 0));
g.CopyFromScreen(p1.X, p1.Y, 0, 0, size);
}
// do stuff here with your Bitmap
}
I'm making an app for Windows 8.1 where it is important to be able to zoom in and examine images in detail. If I just open up the bitmap and zoom in it looks like.
However when I load the image into my app and use the ScrollViewer to zoom in I get.
As it appears to be trying to interpolate pixel values for some sort of anti-aliasing.
How can I get it so that when I zoom in it shows (as best it can) the exact pixels of the image? In particular I'm using the image as the background to a canvas which is contained in a scroll viewer.
I've looked around on here and MSDN and found a pair of related questions, but as yet they don't seem to have solved my exact problem.
A discussion on WPF
A similar issue with a canvas
Older related question on pixel art
A way to use bitmap encoding (which I couldn't get to work)
Similarly phrased question
There is no easy way to go about this, your best option is to use DirectX to render the image much larger so that you can mitigate the effect of WinRT automatically interpolating pixel values.
As someone explained on MSDN and based on this outstanding request I can't see any other way to accomplish this.
Use Win2D
Win2D is a DirectX inter-op library for WinRT. With this you can render the image at a much larger size, and then set the default zoom level for the scrollViewier to be very small. Because of this when you zoom in it will appear to be that you can see the individual pixels without any fuzzy/blurry interpolation because you will actually be seeing groups of 64 pixels or so all as one color. I couldn't find any way to actually override what kind of interpolation gets done so this seems to be the best method.
Download Win2D as a NuGet package using Visual Studio, Win2D's
quickstart guide does a good job explaining some of the setup
Set up your canvas and the draw event and use the DrawImage function to render the image larger
<ScrollViewer x:Name="Scroller" ZoomMode="Enabled"
MinZoomFactor="0.1" MaxZoomFactor="20">
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" CreateResources="create"/>
</ScrollViewer>
In the canvas_draw function.
canvas.Width = original.Width * 10;
canvas.Height = original.Height * 10;
args.DrawingSession.DrawImage(bitmap,new Rect(0,0,original.Width*10,original.Height*10), new Rect(0,0,original.Width,original.Height), 1.0f, CanvasImageInterpolation.NearestNeighbor);
Make sure to set your canvas to be larger as well
In your code behind set the default zoom of your ScrollVieiwer to be appropriate so your image appears to be the same size.
In the page constructor
Scroller.ZoomToFactor (0.1f);
Other Ways Which I Looked Into and Didn't Work
Making the canvas very large and using BitmapEncoder/BitmapDecoder with the interpolation mode set to NearestNeighbor, this introduced lots of visual artifacts even when scaled to a power of 2 size
Render options only appear to be usable in WPF and not WinRT
It may also be possible to use some image manipulation library to simply make the bitmap 10x or so as large and then use that, but I ended up using Win2D instead.
At the moment I'm using Control DrawToBitmap method to capture my WebBrowser like following.
var bmp = new Bitmap(640,480, PixelFormat::Format32bppArgb)
var web = (System.Windows.Forms.Control)sender;
web.DrawToBitmap(bmp, Rectangle(0, 0, 640,480));
My Bitmap supports Alpha channel but this code doesn't save transparency.
Here is the webpage example :
http://jsfiddle.net/zPtPN/
EDIT 2: opacity on embedded browser
With CEF (Chromium Embedded Framework from Google) you should do as follows. This may or may not apply to the default .NET Internet Explorer control.
body
{
background-color: transparent;
}
To overlay this you have to render to a buffer that was cleared. That buffer IS NOT the final rendered raster but an intermediate in-memory buffer that retains VERY MUCH the alpha channel. As long as the buffer is cleared (filled with transparent pixels), you grab the buffer with the full ARGB32 channels and overlay it correctly, you should get what you want.
Best is, you try as far as you can go, then take a screenshot and post a new question specifying that you are using an embedded browser. Also specify the browser version because it will change from one machine to the other: Options for embedding Chromium instead of IE WebBrowser control with WPF/C#
The Bitmap might contain alpha channel information, but not all file formats support it. You should save the image as a *.PNG with ARGB32 lossless mode. A simple *.BMP file will not suffice.
Look at this answer to know not just how to save as PNG but also how to actually get the transparency right:
c# Bitmap.Save transparancy doesn't save in png
To grab transparency from the web page you can try this UGLY, CUMBERSOME, HORRIBLE technique that has tons of problems:
Use a unique color for the body background, like #ffe000. Render the page, grab it as before.
The transparent parts will show the body's background showing through.
At this point you can filter the image by setting its TransparencyKey to the color of the background -OR- by substituting all pixels of that color with a fully transparent pixel color (just change the alpha channel's value from 255 to 0).
Why this is horrible? Because the results will be ugly:
fonts are smoothed and will have shades of that color, so you can't get them partially transparent, they will retain opacity and look horrible much like gifs looked back in the ole'90 (they are called rendering artifacts).
if you use pretty CSS3 stuff like border-radius or box-shadow the same artifacts as above arise: border pixels with shades (anti-aliasing) will look horrible.
Ugly Example here.
So how can you remove these artifacts? You can't.
I highly recommend a completely different approach to your problem.
By the way, what do you want to achieve? Are you using CEF or other embedded browser technology that you want to overlay somehow?
Maybe there are other ways I can help you with....
EDIT: why the ffff <div> does not show
You set the style to:
background-color: transparent; opacity:0;
Now, the background of the <div> will be transparent and show what is behind (the <body>'s background-color). When you set opacity instead, you say to make the whole <div> (contained images and texts included) transparent. Setting it to 0 means totally invisible.
Above is the image i am using. What i am trying to achieve is removing the red portion of the border from the image. How can I achieve this programmatically in windows phone? I found WriteableBitmapExtensions.Crop() method, but I am confused with the arguments (how i can find the x,y position of the image, as well as the size and the width?)
Also another issue I am facing is: I will get the images with differently sized borders, so I can't hardcode the x or y values.
Can anyone suggest a solution, or guide me to solve the issue?
This is not such a trivial thing and you haven't shared any code with us, so I can give you a few suggestions. Every WriteableBitmap has width and height defined. You should be able to access it via
wb.PixelWidth;
wb.PixelHeight;
where wb is your WriteableBitmap (the picture)
Having said that, it's trivial to crop a WriteableBitmap using WriteableBitmapEx library
var croppedBmp = wb.Crop(10, 10, 300, 220);
If your wb was 320x240 and the border was of width 10, then the above Crop call will do the trick - you will take the inner rectangle starting from point (10,10) and ending at (310, 230)
Now to your second issue - not knowing the width of the border. It would help if you know that
Border is of the same thickness on every side of the picture
Border is always in one color only
Assuming that's true, you could think of a simple algorithm (that may not be correct every time, but you can test it and adjust) which would take a few random points, for example
(0,randNumber < wb.PixelHeight), (randNumber < wb.PixelWidth, 0), (wb.PixelWidth, randNumber < wb.PixelHeight), (randNumber < wb.PixelWidth, wb.PixelHeight)
and then move towards the inner part of the picture as long as the neighbour pixel is the same color as the starting pixel. The more points you take randomly, the better chances you have of getting it right. The obvious problem with this is that it may happen that something on the picture is the same color as the border (exactly the same) which will make it seem like the border is wider than it really is. That's why you should take more points.
If you showed some code, I'd be happy to expand the answer.
I must be doing something wrong. I have tried rendering an image to a PDF to both a pdfContext in iOS and a PDF using PDFSharp. When I do it, it's blurry compared to when I open it up in Photoshop or Microsoft's picture preview. So maybe I don't understand what is going on with the image itself. Here is what I know:
Image size is 90 x 20 (w x h). The resolution is 264 ppi.
To draw it in PDFSharp, I do:
XImage image = XImage.FromGdiPlusImage(Properties.Resources.logo);
gphx.DrawImage(image, leftStartDefault, 50, image.PointWidth, image.PointHeight);
I have also tried image.PixelWidth, image.PixelHeight in the above code. Both produce the same blurry result.
In iOS, I do
UIImage *logo = [UIImage imageNamed:#"logo.png"];
[logo drawInRect:CGRectMake(self.frame.size.width - 90 - 60, 20, 90, 20)];
Both produce blurry results. I'm not sure why. I don't know if it's something I am missing with how to choose the size to draw. If I need to ask for a different resolution/size image from our graphics artist, or if it's the way I make the drawing call. If I draw the image at half the size, it is clearer.
e.g.
gphx.DrawImage(image, leftStartDefault, 50, 45, 10);
Any thoughts? thanks.
I realize this is old and perhaps no longer an issue, but I had the same problem.
I found this thread on the PDFSharp forums which was of some use.
As far as I can tell, x pixels on an image in paint does not transfer the same way to y pixels in an image on a pdf (at least in my case). Having an image of 100x100px in paint would apply the same image to the pdf at approximately 153x153px. I have absolutely no idea why this happens, but once I figured out the the factor by which the image size was increased, it became a simple matter to "resize" the image for printing on the pdf.
Like so:
gfx.DrawImage(logo, 0, 0, ApplyTransform(logo.PointWidth), ApplyTransform(logo.PointHeight));
private static double ApplyTransform(double previous)
{
return previous * .6538;
}
EDIT: Upon further research, I believe this is caused by pdf documents not having the concept of pixels in the first place.
Probably, the PDF rasterizing libraries use different, than Photoshop, Windows Viewer ... algorithms of image interpolation, which incorrectly applies for the resulted view. Also they have used different ICC profiles, it also affects the rendering.