Rotate individual letters of the same word in ImageMagick - imagemagick
I'm generating CAPTCHAs for training data and I have a pretty good ImageMagick script going already.
However, one thing I really want is for individual letters of the word to be slightly rotated, see for example this reCAPTCHA:
Is there an easy (or hard) way to accomplish this effect?
I think you need this:
#!/bin/bash
word="theId"
for (( i=0 ; i<${#word} ; i++ )) ; do
rotation=$(((RANDOM%10)*4)) # Generate random rotation for each letter
convert -background none -virtual-pixel none -pointsize 72 label:"${word:i:1}" +distort SRT $rotation miff:-
done | convert -background none - +append result.png
Basically I am creating and rotating one letter at a time and writing them to a MIFF stream, one after the other, and at the end, I am using +append to join together everything I see on the input stream.
If you want to scrunch the letters closer together (TM) you can add -trim +repage just before miff:-
Related
Imagemagick - Getting the usable dimension of an image
I've a process which is creating a file with convert (ImageMagick) based on some parameter, and after that it checks the file and gives back the biggest dimension of it which has real pixels. The commands look like this: convert -size 5000x5000 xc:white -font {font} -pointsize {size} -fill black -draw "{some_occassional_additional_parameter}text 200,2500 \"{text}\"" {some_other_occassional_additional_parameter}{temporary_file} convert {temporary_file}.png -trim +repage -format "%[w]x%[h]\n" info: . It'll result something like: 526x425 This process runs half a million time per day, and it seems to be a huge bottleneck. I'm looking for a solution which can done this in memory, so not always creating a file and check it, but do it in memory somehow. If can speed it up just like 50%, that'd be a huge achievement. Thank You
Not at a computer to test, but change your first command to: convert -size ... xc:... occasionalstuff -format "%#" info: Note that you can, and probably should double quote the "%#" especially if you use expressions containing characters of significance to the shell, though it is not strictly necessary in this specific case.
Apply imagemagick transformation on only part of an image, whilst keeping the rest "stock"?
I have many documents per day that are photographed and I need to organise by QR code. The problem is, zbarimg is struggling to pick up many of the QR codes in the photos, so I have been trialling processing them with imagemagick first, using morphology open, thesholding, etc, which has yielded much better results. The only issue with this is these apply to the whole image, which makes the rest of the file unusable for me, as I deal with the rest of the image based on colours and information which all gets destroyed in the processing. Could anybody give me an example on how I could apply my imagemagick filters to only a part of an image (coordinate based is fine) and leave the rest of the image untouched, so I can continue my process? I will be applying this to all images in a folder, so it's a batch file running this for me in most instances. I have tried using crops, however this obviously leaves me with only the cropped portion of the image, which doesn't actually help when trying to process the rest of the file. I'm running my scripts on Windows 11, if that means anything in terms of the solution. Many thanks! Tom EDIT: Thank you all for the advice given! I solved my problem using the following: convert a.jpg ( -clone 0 -fill white -colorize 100 -fill black -draw "polygon 500,300 500,1500 1300,1500 1300,300" -alpha off -write mpr:mask +delete ) -mask mpr:mask +repage -threshold 50% -morphology open square:4 +mask c.jpg I did post this as an answer, but (and I have no idea why, I'm brand new to stack exchange) my answer was deleted. I used the clone to make the mask with the coordinates needed, then added the threshold and morphology that would make my QR codes more legible! Thanks again everyone, really helped me out on my journey to figure it out :D
You can use -region to specify a region to process. So starting with this: You can then specify a region to colorise with blue and then change the region to blur part of the blue and part of the original: magick swirl.jpg -region 100x100+50+50 -fill blue -colorize 100% -region 100x100+100+100 -blur x20 result.png
The solution using -region may be the most direct. In ImageMagick versions where -region is not supported the same result can usually be achieved by cropping and modifying a clone inside parentheses. magick swirl.jpg ( +clone -crop 100x100+50+50 -fill blue -colorize 50 ) -flatten result.png The cloned, cropped, and and modified piece maintains its original geometry, so the -flatten operation puts it back where it was on the input image after the parentheses.
imagemagick - Restrict elaboration to a region of the image
I need to process a large amount of scans of dot matrix printed documents in order to optimize them for reading with an ocr engine. I used imagemagick to make sure that there are no white spaces between the points of the matrix, so the ocr engine works much better. The problem is performance, pdfs are scanned at 600dpi and processing takes too long. I would like to limit the processing only to the area affected by the zonal ocr, I tried with the "-region" operator but even if it works, the processing takes the same time. This is the command used by the windows command line: convert -density "601.6x600" -units pixelsperinch -monochrome files\1.pdf -region 2000x200+2500+2100 -negate -morphology Thinning "17x17+8+8: -,-,-,-,-,0,0,0,0,0,0,0,-,-,-,-,- -,-,-,-,0,0,0,0,0,0,0,0,0,-,-,-,- -,-,-,0,0,0,0,0,0,0,0,0,0,0,-,-,- -,-,0,0,0,0,-,-,-,-,-,0,0,0,0,-,- -,0,0,0,0,-,-,-,-,-,-,-,0,0,0,0,- 0,0,0,0,-,-,-,-,-,-,-,-,-,0,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,1,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,0,-,-,-,-,-,-,-,-,-,0,0,0,0 -,0,0,0,0,-,-,-,-,-,-,-,0,0,0,0,- -,-,0,0,0,0,-,-,-,-,-,0,0,0,0,-,- -,-,-,0,0,0,0,0,0,0,0,0,0,0,-,-,- -,-,-,-,0,0,0,0,0,0,0,0,0,-,-,-,- -,-,-,-,-,0,0,0,0,0,0,0,-,-,-,-,-" -morphology Thinning "13x13+6+6: -,-,0,0,0,0,0,0,0,0,0,-,- -,0,0,0,0,0,0,0,0,0,0,0,- 0,0,0,-,-,-,-,-,-,-,0,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,1,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,0,-,-,-,-,-,-,-,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,- -,-,0,0,0,0,0,0,0,0,0,-,-" -morphology Close Disk -negate -compress zip r.pdf P.S. I wanted to post on the imagemagick forum, but I didn't find the link to subscribe ...
Issue is resolved here https://github.com/ImageMagick/ImageMagick/discussions/2841. the -region param appears to act after the processing of entire file. Fixed using clone, crop, layer and flatten: magick in.tiff ( +clone -crop 100x100+500+500 -morphology dilate disk ) -layers flatten x2.tiff
Adding white line between text lines
I am trying to do OCR using Tesseract overall results seems acceptable. The images are very very long receipts and we are scanning using scanner, the quality is better. Only issue is that in receipts few characters are joint between two lines Please see the attached sample image. You may see in the first line character 'p' and in the second line character M are joint. This is causing problem in OCR. SO, the real question is may we add a white line or square between every text line ?
You can do that for this image in Imagemagick by trimming the image to remove surrounding white and adding the same amount of black. Then average that image down to one column and looking for the brightest row. I start and stop 4 pixels from the top and bottom to avoid any really bright rows in those regions. Once I find the brightest row, I splice in 4 rows of white between the top and bottom regions divided by that row. This is not the most elegant way. But it shows the potential. One could likely pipe the list of row values to AWK and search for the max value in more efficient manner than saving to an array and using a for loop. Unix syntax with Imagemagick. Input: max=0 row=0 arr=() arr=(`convert text.png -fuzz 50% -trim -background black -flatten -colorspace gray -scale 1x! -depth 8 txt:- | tail -n +2 | sed -n 's/^.*gray[(]\(.*\)[)]$/\1/p'`) num=${#arr[*]} #echo "${arr[*]}" for ((i=4; i<num-4; i++)); do val="${arr[$i]}" max=`convert xc: -format "%[fx:$val>$max?$val:$max]" info:` row=`convert xc: -format "%[fx:$val==$max?$i:$row]" info:` #echo "$i $val $max $row" done convert text.png -gravity north -splice 0x4+0+$row text2.png If you want less space, you can change to -splice 0x1+0+$row, but it won't change much. It is not writing over your image, but inserting white between the existing rows. But by doing the processing above, your OCR still may not recognize the p or M, since the bottom of the p is cut off and appended to the M. If you have more than two lines of text, you will have to search the column for approximately evenly spaced maxima.
Adding border to multiple images using gimp?
I have around 100 pictures that i want to add white border to it all at once. I use Linux and also use gimp ,.. please suggest me something to do so online of offline. and one more thing that i have tried convert option on imagemagick but nothing happen.
If you want to do 100 all at once you will be best off using ImageMagick's mogrify command like this to add a 10 pixel white border around all images: mogrify -mattecolor white -frame 10x10 image*.jpg If the images are not all in a single directory, you can do the following which will do the same thing across all subdirectories of the one you are currently in: find . -name \*.jpg -exec convert "{}" -mattecolor white -frame 10x10 "{}" \; Obviously you can change the 10 to a different number of pixels if you wish. Please make a backup before using this as I may have misunderstood your needs. Updated If you want a drop shadow, you really need to be working with PNG rather than JPG since the former supports transparency and the latter doesn't - but IM can convert your JPEGs to PNGs anyway. I use the following command for drop shadows: convert image.jpg \( -clone 0 -background black -shadow 80x3+0+8 \) -reverse -background none -layers merge +repage image.png So, I would apply that to a pile of images like this: #!/bin/bash for f in *.jpg; do new=${f%%jpg}png # Work out new name = original name minus "jpg" + "png" echo Processing $f into $new convert "$f" \( -clone 0 -background black -shadow 80x3+0+8 \) -reverse -background none -layers merge +repage "$new" done