Determine image size of text drawn with ImageMagick? - imagemagick

I'd like to generate some font-effects using convert but don't see an easy way to calculate a canvas size. The method I have now is to generate the text as desired, such as convert label:ABCDEF then load the resulting image to get its size. This seems highly inefficient and troublesome.
Is there a command option or method to simply calculate the metrics of the resulting text?

the best solution I actually see is:
convert -verbose label:ABCDEF png:- >/dev/null
which results in the following message on stderr:
label:ABCDEF=>ABCDEF LABEL 53x15 53x15+0+0 16-bit DirectClass 0.020u 0:00.010
The requested size is in column 3: 53x15

There is a way to get the text metrics a bit more directly, though leu's size option is also good. Using the -debug annotate option you can then search for the Metrics: output which includes the text size.

Related

Create fixed-size montage of images with missing files

Setting
Suppose we have a list of N elements of which an element can either be a path to an image (e.g. a.jpg) or NULL indicating that a file is missing.
Example (N = 6): a.jpg,NULL,c.jpg,NULL,NULL,f.jpg
All mentioned images (a.jpg, c.jpg, f.jpg) are guaranteed to have the same resolution.
Task
Create a fixed-width montage (e.g. out.jpg) in which NULL values are replaced with black images whose resolutions are consistent with the common resolution of a.jpg, c.jpg, f.jpg. I would like to abstain from creating an actual black.jpg and would prefer to create the image on-the-fly as needed.
Using ImageMagick's "montage" command, if your images are known dimensions so you can include that in the command, and if you can generate a text file "list.txt" of the image files and put "xc:black" on each line that has no image like this...
image00.png
image01.png
image02.png
image03.png
image04.png
xc:black
image06.png
image07.png
xc:black
xc:black
image10.png
image11.png
You can run the ImageMagick "montage" command something like this...
magick montage #list.txt -tile 3x4 -geometry 160x160+3+3! out.png
The "#" in front of the name of the text file tells IM to read the input images from there. The "-tile" describes how many columns and rows will be in the result. The "-geometry" setting is where you put the dimensions of the images and the spacing between columns and rows. The "xc:black" images are single black pixels, but the exclamation point forces them to the W and H dimensions in the "-geometry" argument.
That will create black images everywhere you have "xc:black" in the list. If you want to fill between the spaces with black also, add "-background black" to the command.
That works for me with IMv7 and "magick montage ..." For IMv6 you just use "montage". I'm pretty sure everything else about the command would work the same way.

How is the colon operator defined in the context of image magick command line usage

I can't find any documentation for this.
I have found examples in the image magick documentation which use a colon but nothing explicit about how the colon is interpreted.
The examples are confusing ;
magick -size 640x480 pattern:checkerboard checkerboard.png
suggests it sets the attribute on the left (pattern) to the value on the right (checkerboard)
but then
magick -size 640x480 -depth 8 rgb:image image.png
suggests it sets file type of image - the thing on the right - to what is left of it
EDIT
This was all just a brain fart on my part; I was thinking (for various reasons) of "image" as a thing being made/assigned rgb which makes no sense (as "image" is a file name / input parameter).
The sensible interpretation is obviously of rgb as a thing (image of type rgb) being assigned the info in the file "image" .
So from these two examples at least, it appears the colon just assigns/applies the right hand operand to the left hand operand as you would expect.
There are a couple of ways the colon is used.
Some options which create their own canvas have a colon, for example:
xc: creates a canvas
gradient:colourA-colourB creates a gradient from colourA to colourB
tile: creates a repeated tile
radial-gradient: creates a radial gradient
rose: creates the built-in rose image
pattern: for a built-in pattern as you saw
logo: for the ImageMagick logo
label: for text labels
caption: for text captions
Then the colon sometimes prefixes a filename to tell ImageMagick what is in it. This is your rgb: use case, and it is necessary because the filename doesn't happen to end in .rgb. Other examples of this are:
gray: when the greyscale input file doesn't end in .gray
tif:fd:5 read a TIFF from file descriptor 5
Or to tell it to write a specific variant of a file, e.g.:
PNG8: to write a palettised PNG
PNG24: to write an RGB888 PNG
PNG32: to write an RGBA8888 PNG with alpha
PTIF: to write a pyramid TIFF
BMP3: to write a version 3 Microsoft BMP file
fd:3 write output on file descriptor 3
gif:fd:4 write output as GIF on file descriptor 4
There is some documentation here.

Saving figures in julia

Two questions regarding Winston package
How do you change dimensions of an image using savefig?
I have a 256x320 matrix that i use to plot an image using Winston package with the imagesc() command and then when i try to save it using savefig("picture.png","width","height") i get the same 512x512 pixels picture and i can't resize it, no matter how i change values : width, height.
Is it possible to export a FramedPlot chart to an image?
Regards
Mike
To answer the first part, savefig() takes the variable number of positional arguments and named key value pairs, so the right way of calling your function is,
julia>savefig("name.png","width",10,"height",20)

How to remove white space between ImageMagick's montage tiles?

I current have code that build a montage using ImageMagick. This is my line of code:
montage -mode Concatenate -tile ${tile} -geometry ${geometry}+0+0 ${input} ${output}
I'm using -label ${label} to name my labels (in my input var).
This gets me a montage with a lot of white space, like that:
I checked on the manual and forums but everyone seem to agree that the way to do this is to use concatenate or geometry +0+0. I am already using those and it does not work. I also read that the font should be automatically chosen to fit the free space. Right now, there is way too much white space.
My goal: To get the white space (between the tiles on the vertical) to fit the current labels height and nothing more.
If you have an idea, I would be really happy.
Thank you anyway guys!
PS: It also doesn't work without labels. I get:
PPS: I'm sorry if my english is not really good, I am french from Montréal, Qc, Canada.
UPDATE: Those are my settings:
tile=4x3
geometry=386x305
The additional white space is coming from your geometry setting. The options -geometry 386x305+0+0 is adding an additional 15px between the image and the label.
If you omit the WxH and add a non-zero value to the offset -geometry +0+15, then you'll have additional white space after the label.
To limit the white space to text height, and nothing more, just keep the option as -geometry +0+0.
I also read that the font should be automatically chosen to fit the free space.
I think that's reversed. The white space is determined by the typeface of the font. I wouldn't say fonts automatically adjust <blank>, but default to <blank>. It's always a good idea to define the font & pointsize.

ImageMagick resize: Do really nothing for the "Only Shrink Larger" case

The original image:
http://www.tiaoyue.com/img/_test/original.jpg
(2,457 bytes)
Try to get a thumbnail by ImageMagick:
convert \
http://www.tiaoyue.com/img/_test/original.jpg \
-thumbnail 200x200\> \
SecondaryCompression.jpg
Or in Windows:
convert ^
http://www.tiaoyue.com/img/_test/original.jpg ^
-thumbnail 200x200^> ^
SecondaryCompression.jpg
Get the file:
SecondaryCompression.jpg
(2,452 bytes)
Can I get the target file (SecondaryCompression.jpg) without secondary compression, only copy of original image? (2,457 bytes of the image)
Reference:
http://www.imagemagick.org/Usage/resize/#shrink
The real problem with your 'convert' command is not that the file undergoes a 'secondary compression' as you called it.
The real problem is that some of the pixels get their color values changes very slightly (which in turn does allow a better or, maybe even worse, compression result for the total file).
So you should investigate how you can prevent the color changes first!
To document + verify the color changes for each single pixel, run these commands:
convert http://www.tiaoyue.com/img/_test/original.jpg original.txt
convert SecondaryCompression.jpg SecondaryCompression.txt
sdiff -sbB SecondaryCompression.txt original.txt
Hint: The TXT output format of convert is a textual representation of the coordinate position of each pixel and its respective color values (these values are given in 3 different ways: decimal RGB (or CMYK) values, hex RGB (or CMYK) values, human readable color names (when possible). If you see the format once, you'll understand it immediately.
One can establish that in total 1415 pixels have changed color values, out of a total of 7500 pixels. That's 18.86% of pixels changed.
To create a visual representation for the pixel differences, run:
compare original.jpg SecondaryCompression.jpg delta1.jpg
compare original.jpg SecondaryCompression.jpg -compose src delta2.jpg
The first image (delta1.jpg, far left) paints those pixels in red which have different color values, using the original.jpg as a light-gray background image.
The second image (delta2.jpg, second from left) paints only pixels in red which have different colors, and paints identical color values as white pixels.
The third image (second from right) is your original JPEG. The fourth one (far right) is your 'unaltered' thumbnail (in reality with some subtle changes for some pixels).
I've no time right now to investigate the reason for the slight color changes (and can't give a reason out of the top of my head), but will maybe return later to this topic.

Resources