convert-im6.q16: no images defined `test.jpg' # error/convert.c/ConvertImageCommand/3258 - ghostscript

I have an issue that I don't understand. I try to convert a PDF into a JPEG but I have the error :
convert-im6.q16: no images defined 'scan0476.jpg' # error/convert.c/ConvertImageCommand/3258
Here is the command line :
convert -density 200 "/opt/maarch/dispatcher/tmp//DGS_scan0476.pdf[0]" -quality 100 -geometry x2000 -crop x500+0+1500 "scan0476.jpg"
The /opt/maarch/dispatcher/tmp/ folder have 777 rights and my pdf is good
The library is well installed with all the dependency needed
Thanks in advance

This worked fine with my test:
#!/bin/sh
convert -density 200 "$1" -quality 100 -geometry x2000 -crop x500+0+1500 "$1.jpg"
results:
$ file my.pdf.jpg JPEG image data, JFIF standard 1.01, aspect ratio, density 200x200, segment length 16, baseline, precision 8, 1545x500, components 3

Related

How to batch-resize PNG files?

I have a number of PNG image files that I'd like to increase in size. I do not want to rescale the image. I just want to extend the white background further down and to the right. In GIMP terms what I want is to increase the Canvas Size, and cover the increased area with white pixels, in a batch context. The input images may be different sizes, but the output images should all be a fixed size (e.g.: 1280 x 720 pixels).
I've tried this with various online tools, with GIMP, and with a very old version of Photoshop. Most of the tools I've tried to date do one of the following which I don't want:
Rescale the existing image to cover the new canvas size, or
Center the starting image and extend the canvas in all directions, or
Fail to perform this in a batch mode.
I just want to extend existing PNG images with additional white pixels down and to the right. What's the easiest way to do this to a large number of files?
imagemagick is a common tool for this. the -crop operation combined with -gravity can probably do what you want.
magick input.jpg -crop 1000x1000+0+0\! -background white -flatten output.png
source for the magick spell: https://legacy.imagemagick.org/Usage/crop/
In ImageMagick, you process a whole folder of images using mogrify. You can extend them using -extent. With mogrify, it is wise to first create a new empty directory to hold the results. So
cd image_directory
mogrify -format png -path path/to/new_directory -background white -gravity northwest -extent WxH *.png
Where WxH, is your desired final width and height after padding with the white. This assumes that all images will be padded to the same width and height
Expand By Size
cd test1
mogrify -format png -path ../test2 -background white -gravity northwest -extent 500x500 *.jpg
Expand By Percent
cd test1
mogrify -format png -path ../test2 -background white -gravity northwest -extent 150x150% *.jpg
For ImageMagick 7, add magick before mogrify. So "magick mogrify ..."
The ImageMagick command that did what I needed used "convert" with the -geometry and -composite arguments. In a Windows batch file context:
for %%a in (img*.png) do (
magick convert -size 1280x720 xc:white "%%a" -geometry 512x384+40+40 -composite "work-%%~na.pdf"
)

mix single channel images into color image

each representing a channel and I want to merge them into a single one, like RGB image. The images are RAW, so no file header. I have managed to mix them with
cat imgPl0.raw imgPl1.raw imgPl2.raw >> img.rgb
but this is mixing the planes one after the other, but is there a way to do an interlaced mix ?
Maybe using imagemagick there is another way ?
Well, what I need at the output is a rgb image (not a png, sadly imagemagick is creating a png as output) containing the data interlaced. To be more explicit, cat-ing the images is going to make a rgb image plane-interlaced (that is rrrrrr...ggggggg...bbbbbbb). What I want is an operation that is creating a rgb image line-interlaced (that is rrr...ggg...bbb...rrr...ggg...bbb...rrr...ggg...bbb...). Sorry for not being explicit from the beginning.
About the data, it seems it is 12 bpp or 14 bpp little endian
ImageMagick offers a few techniques, but you'll need to be responsible for defining all the information missing from the headers. Stuff like image size, quantum depth, and colorspace.
One approach.
convert -size 70x46 -depth 8 \
r:imgPl0.raw g:imgPl1.raw b:imgPl2.raw \
-set colorspace RGB -combine -colorspace sRGB \
output.rgb
Another option is to create a blank canvas, and copy the data from the raw files over to the correct canvas channels.
convert -size 70x46 xc: -depth 8 \
r:imgPl0.raw -compose CopyRed -composite \
g:imgPl1.raw -compose CopyGreen -composite \
b:imgPl2.raw -compose CopyBlue -composite \
-colorspace sRGB output.rgb
Other examples can be found here.
Also note: I'm assuming that these .raw data files only contain single channel samples, are unsigned character color sizes, and have a 70x46 image size. YMMV
Update
Well, what I need at the output is a rgb image (not a png, sadly imagemagick is creating a png as output)
Sorry about that. Just switch output.png to output.rgb. ImageMagick will do the rest.
About the data, it seems it is 12 bpp or 14 bpp little endian
Adjust -depth from 8 to 12, or 14 bits-per-part.
There's also a -endian LSB option, but I don't think that's needed.
What I want is an operation that is creating a rgb image line-interlaced
Easy. Set the -interlace Line options.
So... My previous answer is still helpful, but just needs some additional options.
convert -size 70x46 -depth 12 \
r:imgPl0.raw g:imgPl1.raw b:imgPl2.raw \
-set colorspace RGB -combine -colorspace sRGB \
-interlace Line output.rgb
or
convert -size 70x46 xc: -depth 12 \
r:imgPl0.raw -compose CopyRed -composite \
g:imgPl1.raw -compose CopyGreen -composite \
b:imgPl2.raw -compose CopyBlue -composite \
-colorspace sRGB -interlace Line output.rgb
Hope that get's you close.
If your data is 8 bits per sample, you can do it like this which whilst not very efficient, doesn't require any code writing or compiling or anything:
#!/bin/bash
# Bytes per row
bpr=100
row=0
# Loop through all rows of file
while :; do
# Read a row from each channel and output on stdout redirected to result.rgb
for ((chan=0;chan<3;chan++)); do
dd if=imgPl${chan}.raw bs=$bpr count=1 skip=$row > row.tmp 2> /dev/null
[ ! -s row.tmp ] && exit
cat row.tmp
done
((row+=1))
done > result.rgb

How to shrink and optimize images?

I'm currently using jpegoptim on CentOS 6. It lets you set a quality and file size benchmark. However, it doesn't let you resize the images.
I have 5000 images of all file sizes and dimensions that I want to shrink to a max width and max file size.
For example, I'd like to get all images down to a maximum width of 500 pixels and 50 KB.
How can I shrink and optimize all of these images?
You can do this with ImageMagick, but it is hard to say explicitly which way to do it as it depends on whether all the files are in the same directory and also whether you have or can use, GNU Parallel.
Generally, you can reduce the size of a single image to a specific width of 500 like this:
# Resize image to 500 pixels wide
convert input.jpg -resize 500x result.jpg
where input.jpg and result.jpg are permitted to be the same file. If you wanted to do the height, you would use:
# Resize image to 500 pixels high
convert input.jpg -resize x500 result.jpg
since dimensions are specified as width x height.
If you only want to reduce files that are larger than 500 pixels, and not do any up-resing (increasing resolution), you add > to the dimension:
# Resize images wider than 500 pixels down to 500 pixels wide
convert image.jpg -resize '500x>' image.jpg
If you want to reduce the file size of the result, you must use a -define to guide the JPEG encoder as follows:
# Resize image to no more than 500px wide and keep output file size below 50kB
convert image.jpg -resize '500x>' -define jpeg:extent=50KB result.jpg
So, now you need to put a loop around all your files:
#!/bin/bash
shopt -s nullglob
shopt -s nocaseglob
for f in *.jpg; do
convert "$f" -resize '500x>' -define jpeg:extent=50KB "$f"
done
If you like thrashing all your CPU cores, do that using GNU Parallel to get the job done faster.
Note that if you have a file that is smaller than 500px wide, ImageMagick will not process it so if it is smaller than 500 pixels wide and also larger than 50kB, it will not get reduced in terms of filesize. To catch that unlikely edge case, you may need to run another find afterwards to find any files over 50kB and then run them through convert but without the -resize, something like this:
find . -type f -iname "*.jpg" -size -51200c -exec convert {} -define jpeg:extent=50KB {} \;

Command line batch image cropping tool

is there any lightweight command line batch image cropping tool(Linux or Windows) which can handle a variety of the formats ?
In Linux you can use
mogrify -crop {Width}x{Height}+{X}+{Y} +repage image.png
for CLI image manipulation
Imagemagick's convert does the trick for me (and much more than cropping):
convert -crop +100+10 in.jpg out.jpg
crops 100 pixels off the left border, 10 pixels from the top.
convert -crop -100+0 in.jpg out.jpg
crops 100 pixels off the right, and so on. The Imagemagick website knows more:
http://www.imagemagick.org/Usage/crop/#crop
Imagemagick is what you want -- tried and true.
I found nconvert pretty handy so far.
for f in final/**/*;
do
convert -crop 950x654+0+660 "$f" "${f%.jpg}".jpg
done
This script loops through all the sub-folders and crops the .jpg files.
macOS has sips image processing tool integrated. Cropping functions available are:
-c, --cropToHeightWidth pixelsH pixelsW
--cropOffset offsetY offsetH
Easy with sips: just set the offset to start the cropping:
sips --cropOffset 1 1 -c <height> <width> -o output.png input.png
I have scanned some pages and all ~130 pages needs the lower ~1/8 of the page cut off.
Using mogrify didn't work for me,
a#a-NC210-NC110:/media/a/LG/AC/Learn/Math/Calculus/Workshop/clockwise/aa$ mogrify -quality 100 -crop 2592×1850+0+0 *.jpg
mogrify.im6: invalid argument for option `2592×1850+0+0': -crop # error/mogrify.c/MogrifyImageCommand/4232.
However convert did:
a#a-NC210-NC110:~/Pictures/aa$ convert '*.jpg[2596x1825+0+0]' letter%01d.jpg
a#a-NC210-NC110:~/Pictures/aa$
I learnt this here under the Inline Image Crop section.
Notice my syntax: I had to put my geometry in brackets: [].
Using the successful syntax above but with mogrify simply didn't work, producing:
a#a-NC210-NC110:~/Pictures/aa$ mogrify '*.jpg[2596x1825+0+0]' letter%01d.jpg
mogrify.im6: unable to open image `letter%01d.jpg': No such file or directory # error/blob.c/OpenBlob/2638.
Linux a-NC210-NC110 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:12 UTC 2014 i686 i686 i686 GNU/Linux
Lubuntu 14.04 LTS

Can ImageMagick return the image size?

I'm using ImageMagick from the command line to resize images:
convert -size 320x240 image.jpg
However, I don't know how to determine the size of the final image. Since this is a proportional image scale, it's very possible that new image is 100x240 or 320x90 in size (not 320x240).
Can I call the 'convert' command to resize the image and return the new image dimensions? For example, pseudo code:
convert -size 320x240 -return_new_image_dimension image.jpg // returns the new resized image dimensions
-ping option
This option is also recommended as it prevents the entire image from being loaded to memory, as mentioned at: https://stackoverflow.com/a/22393926/895245:
identify -ping -format '%w %h' image.jpg
man identify says:
-ping efficiently determine image attributes
We can for example test it out with some of the humongous images present on Wikimedia's "Large image" category e.g. this ultra high resolution image of Van Gogh's Starry Night which Wikimedia claims is 29,696 × 29,696 pixels, file size: 175.67 MB:
wget -O image.jpg https://upload.wikimedia.org/wikipedia/commons/e/e8/Van_Gogh_-_Starry_Night_-_Google_Art_Project-x0-y0.jpg
time identify -ping -format '%w %h' image.jpg
time identify -format '%w %h' image.jpg
I however observed that -ping at least in this case did not make any difference on the time, maybe it only matters for other image formats?
Tested on ImageMagick 6.9.10, Ubuntu 20.04.
See also: Fast way to get image dimensions (not filesize)
You could use an extra call to identify:
convert -size 320x240 image.jpg; identify -format "%[fx:w]x%[fx:h]" image.jpg
I'm not sure with the %w and %h format. While Photoshop says my picture is 2678x3318 (and I really trust Photoshop), identify gives me:
identify -ping -format '=> %w %h' image.jpg
=> 643x796
(so does [fx:w] and [fx:h])
I had to use
identify -ping -format '=> %[width] %[height]' image.jpg
=> 2678x3318
I don't know what's going on here, but you can see both values on standard output (where the width and height before the => are the correct ones)
identify -ping image.jpg
image.jpg PAM 2678x3318=>643x796 643x796+0+0 16-bit ColorSeparation CMYK 2.047MB 0.000u 0:00.000
The documentation says %w is the current width and %[width] is original width. Confusing.
%w and %h may be correct for most uses, but not for every picture.
If you specify option -verbose, convert prints:
original.jpg=>scaled.jpg JPEG 800x600=>100x75 100x75+0+0 8-bit sRGB 4.12KB 0.020u 0:00.009
^^^^^^

Resources