Convert PDF to a bw image with sharp edges - image

I need to convert many PDF pages to images, containing simple shapes such as rectangles or triangles. Texts and composed shapes consist of lines are also in the PDFs.
Example shape from a screenshot out of a PDF:
Note: The screenshot is unsharp because I've used Windows' print function in order to separate a single page. It seems to be that this function converts PDFs to images and then saves them as PDF file.
Requirements of images:
sharp edges, a staircase is desired without any grey values
lines of equal thickness
relatively low resolution (<300 dpi would be wonderful)
black & white only
I'd like to work with ImageMagick because it provides a lot of features. I guess anti-aliasing, black-threshold and sharpen are relevant to this, but I haven't reached my desired results.
PDF example of a similar shape

Something like this, maybe?
magick -density 288 -background white ~/Desktop/drawsvg.pdf -flatten -colorspace gray result.png

Related

Detecting anti-aliased or undersampled text image

I have an image that is essentially a text document (black and white) but due to anti-aliasing/undersampling applied during scanning, the image contains a lot of color, light tone pixels and is thus saved as a full-color image i.e: takes a lot of space.
My goal is to be able to detect Black and White image candidates in order to convert them from full color to B&W which dramatically reduces their size.
Is there a way to detect such anti-aliased/undersampled images? Doing color pixel analysis doesn't help because the colored pixels end up being close in amount to the black pixels... Essentially I want to be able to detect that the colored pixels come from anti-aliasing/undersampling a black & white image and not from a picture type image.
Here is an example image:
As you can see there are many more colors than just black. However this image is a good candidate for Black & White / Greyscale conversion instead of full color. How can I detect such images? Please note that in this example the colors tend to be on the grey side but there are many cases where they are cyan or brown etc.
I think it is a valid question. I don't have 50 reputation to post a comment so I will post this as an answer.
Basically, in a black and white anti-aliased image the various grey colors are opacity differences of the black color. If we observe those pixels they will be like these listed below. So, if the operation is a color manipulation then apply the same opacity picked up from those grey pixels to the new color.
rgba(0,0,0,0.6)
rgba(0,0,0,0.9)
rgba(0,0,0,0.5)
rgba(0,0,0,0.9)
rgba(0,0,0,0.6)
rgba(0,0,0,0.1)
rgba(0,0,0,0.5)
In my opinion, the pixels other than grey, in this example image, cyan and brown as it appears can be safely ignored because they seemed like not part of the original text. If there were a few more example images of non grey pixels would have been good. But if we cannot ignore them just need to get the pixel opacity and apply the same color manipulation. In other words we treat them as black pixels.

How to trim/crop an image uniformly in ImageMagick?

Assume I have an original image (gray backgorund) with a black circle a bit down to the right (not centered), and the minimum space from any edge of the circle to the edge is, lets say, 75px. I would like to trim the same amount of space on all sides, and the space should be the maximum space possible without cropping the actual object in the image (area in magenta in image). Would love to hear how this could be solved.
Thanks in advance!
If I understand the question correctly, you want to trim an image not based on minimum bounding rectangle, but outer bounding rectangle.
I would do something like this..
Given I create an image with.
convert -size 200x200 xc:gray75 -fill black -draw 'circle 125 125 150 125' base.png
I would drop the image to a binary edge & trim everything down to the minimum bounding rectangle.
convert base.png -canny 1x1 -trim mbr.png
This will generate mbr.png image which will also have the original page information. The page information can be extracted with identify utility to calculate the outer bounding rectangle.
sX=$(identify -format '%W-(0 %X)-%w\n' mbr.png | bc)
sY=$(identify -format '%H-(0 %Y)-%h\n' mbr.png | bc)
Finally apply the calculated result(s) with -shave back on the original image.
convert base.png -shave "${sX}x${sY}" out.png
I assume that you want to trim your image (or shave in ImageMagick terms) by minimal horizontal or vertical distance to edge. If so this can be done with this one liner:
convert circle.png -trim -set page "%[fx:page.width-min(page.width-page.x-w,page.height-page.y-h)*2]x%[fx:page.height-min(page.width-page.x-w,page.height-page.y-h)*2]+%[fx:page.x-min(page.width-page.x-w,page.height-page.y-h)]+%[fx:page.y-min(page.width-page.x-w,page.height-page.y-h)]" -background none -flatten output.png
This may look complicated but in reality isn't. First trim the image. The result will still have stored information on page geometry including original width, height and actual offsets. With this info I can set the page geometry (correct width & height and new offsets) using ImageMagick FX expressions. Finally, flattening the image will produce desired output.

To remove background greyed pixels from image

I want to remove background unnecessary greyed pixels in above image.
May i know how to do that.
Quick and dirty with ImageMagick:
convert 9AWLa.png -blur x1 -threshold 50% out.png
Somewhat better, still with ImageMagick:
convert 9AWLa.png -morphology thicken '1x3>:1,0,1' out.png
Updated Answer
It is rather harder to keep the noisy border intact while removing noise elsewhere in the image. Is it acceptable to trim 3 pixels off all the way around the edge, then add a 3 pixel wide black border back on?
convert 9AWLa.png -morphology thicken '1x3>:1,0,1' \
-shave 3x3 -bordercolor black -border 3 out.png
Some methods that come to my mind are
If the backgroud is gray color rather than sparse black dots then you can convert the image in binary by thresholding it with proper value of grayscale. i.e. all values above particular values of pixel are white and all values below that are black. Something like this.
Another thing you can do is first smoothing the picture my some filter like mean or median filter and then converting into binary presented in previous point.
I think in this way the unnecessary background can be removed

Tool for resizing images to square with white background

Now I have a lots of pictures. they comes in many dimensions,aspect ratios. for example. 100px*500px,600px*200px,1000px*700px.
Now I want a tool for me to resize all the images to square shape , but never distort or stretch the image , padding white background instead.
the result I want , 500*500 , 600*600, 1000*1000, but have white background.
I find irfanview can not make it.
thanks.
Use ImageMagick thumbnailing capabilities with -extent and -background white options: see this documentation.

Crop a face/head using oval/polygonal shapes without using flash? (ajax or html5?)

My mission is to let users upload their own photos then the site crops the face+hair and pastes them on an ecard. The tough part is that I'm not allowed to use flash =/
I understand there are ajax or js face detection solutions out there, but what stumps me is how do I crop an odd shaped pattern. Imagemagick/graphicsmagick as I know can only crop a rectangular or square shaped object (please correct me if I'm wrong). Will this pretty much destroy the whole idea until im has the functionality to crop odd shapes? or are there other ways to crop circles or polygons?
An idea popped up to maybe allow the user to draw some lines in their photo for cropping then maybe the site converts the lines to a vector and fills a color around the lines, the colors are then converted by im to transparent... but then I have no idea how to start this one.. probably not possible at the moment (?).
I'm running out of ideas :(
I have just successfully created a crop :) although not perfect it should work in android or iphone/ipad.
Basically I used a js plotting tool to mark the coordinates, save all those coordinates somewhere.
Then use the coordinates for imagemagick, it appears that although IM doesn't really crop odd shapes it can however use 'mask' to convert the bg of the photo by combining the stencil (where we draw the lines using our coordinates, fill the bg with #000000 color) and the original photo.
The result should be the crop we are looking for :) now we added in some feathering since it's kinda edgy. All this using imagemagick.
Now all we needed are curvier lines since I used 'path' in IM which doesn't really offer a smooth crop. Someone suggested to use 'cubic curves' but may require additional coding since it needs some parameters for each coordinate.
This command will create our stencil (the long set of numbers are our coordinates):
convert -size 450x125 xc:black -fill white -stroke black -draw "path 'M +60+9 +94+18 +96+19 +84+27 +92+36 +97+43 +103+56 +102+58 +109+66 +109+74 +101+68 +98+76 +98+84 +95+88 +98+91 +106+95 +110+99 +111+103 +99+106 +89+108 +73+112 +56+109 +40+109 +26+103 +37+97 +46+91 +48+88 +39+80 +36+71 +32+78 +27+72 +30+61 +35+55 +42+41 +30+37 +40+24 +51+14 +156+9 +197+6 +236+8 +269+16 +265+36 +248+50 +222+52 +213+35 +198+24 +174+18 +155+13 +60+9'" stencil.gif
We will then combine the stencil with the original image (which should bring out our transparent 'crop'):
convert original.jpg stencil.gif -alpha off -compose CopyOpacity -composite combined.png
Finally we feather out the edges:
convert combined.png -alpha set -virtual-pixel transparent -channel A -blur 0x0.7 -level 50,100% +channel -background none -flatten final.png
This is how it works now : https://lh6.googleusercontent.com/_2lSoW37_zqo/TYCD65Vu4zI/AAAAAAAAEcc/vjlCPM54FTI/s800/theoryinpractice.jpg 
That's about it, I hope this helps someone.

Resources