What converter(like imagemagick) can be used to convert images with exif data preserving it?
What if I downscale images 4 times? Should I also change the focal length?
Data I have extracted from my JPG photo with exiftool
Focal Length : 50.0 mm (35 mm equivalent: 50.0 mm)
EDIT:
Seems imagemagick preserve exif data:
mogrify -resize 25% -path output_foler/ *.JPG
I believe newer versions of Imagemagick should preserve the metadata. A fall back would be to use Exiftool to copy the data with a command like exiftool -tagsfromfile OldFile -all:all NewFile.
Both of those are platform independent. To be more precise with other programs, you will need specify your OS. For example, with Windows, you can use Irfanview to convert images and it will retain most metadata as long as you enable those options.
Related
I'd like to batch convert .heic images (e.g. iPhone photograph) to .jpg files with imagemagick, with the goal of retaining as much of the quality from the original image as possible. To be clear, the resulting output size is not a concern.
I've been using
magick input.heic -quality 100% output.jpg
Is it possible to do better?
No, its not possible to do better per ImageMagick's website:
Set the quality to 100 to produce lossless HEIC images. Requires the libheif delegate library.
I interpret lossless as NOTHING is lost from original picture. However since you ARE converting to another file type maybe its possible you lose something, are you seeing any artifacts/issues?
I would like to have the best compression ratio of a sequence of similar grayscale images. I note that I need an absolute lossless solution (meaning I should be able to check it with an hash algorithm).
What I tried
I had the idea to convert my images into a video because there is a chronology between images. The encoding algorithm would compress using the fact that not all the scene change between 2 pictures. So I tried using ffmpeg but I had several problems due to sRGB -> YUV colorspace compression. I didn't understand all the thing but it's seems like a nightmare.
Example of code used :
ffmpeg -i %04d.png -c:v libx265 -crf 0 video.mp4 #To convert into video
ffmpeg -i video.mp4 %04d.png #To recover images
My second idea was to do it by hand with imagemagik. So I took the first image as reference and create a new image that is the difference between image1 and image2. Then I tried to add the difference image with the image 1 (trying to recover image 2) but it didn't work. Noticing the size of the recreated picture, it's clear that the image is not the same. I think there was an unwanted compression during the process.
Example of code used :
composite -compose difference 0001.png 0002.png diff.png #To create the diff image
composite -compose difference 0001.png diff.png recover.png #To recover image 2
Do you have any idea about my problem ?
And why I don't manage to do the perfect recover with iamgemagik ?
Thanks ;)
Here are 20 samples images : https://cloud.damien.gdn/d/f1a7954a557441989432/
I tried a few ideas with your dataset and summarise what I found below. My calculations and percentages assume that 578kB is a representative image size.
Method 1 - crush - 69%
I just ran pngcrush on one of your images like this:
pngcrush -bruteforce input.png crushed.png
The output size was 400kB, so your image is now only taking 69% of the original space on disk.
Method 2 - rotate and crush - 34%
I rotated your images through 90 degrees and crushed the result:
magick input.png -rotate 90 result.png
pngcrush -bruteforce result.png crushed.png
The rotated crushed image takes 34% of the original space on disk.
Method 3 - rotate and difference - 24%
I rotated your images with ImageMagick, then differenced two adjacent images in the series and saved the result. I then "pngcrushed" that which resulted in 142kB, or 24% of the original space.
Method 4 - combined to RGB - 28%
I combined three of your single channel images into a 3-channel RGB image and pngcrushed the result:
magick 000[123].png -combine result.png
pngcrush -bruteforce result.png crushed.png
That resulted in a 490kB file containing 3 images, i.e. 163kB per image or 28% of the original size.
I suspect video with "motion" estimation/detection would yield the best results if you are able to do it losslessly.
You might get some gain out of MNG, which is intended for lossless animation compression. You can use libmng to try it out.
I need to convert PNG to JPEG,JPEG 2000 using ImageMagick and Matlab. I want to compress all data with ratio ( e.g. 10) and then specify some file size? Any idea or solution to achieve the specific file size? How can I do it? Thanks
Imagemagick can create a JPG of your desired file size. See http://www.imagemagick.org/Usage/formats/#jpg
-define jpeg:extent={size}
As of IM v6.5.8-2 you can specify a maximum output filesize for the JPEG image. The size is specified with a suffix. For example "400kb".
Unable to convert a JPEG image into a 300 DPI PNG image using ImageMagick.
After conversion the PNG image is 72 DPI only. I'm using ImageMagick 6.9.0-0 Q16 x86 and Ghostscript v9.15.
Below is the line I use in my Perl script:
system("\"$imagemagick\" -set units PixelsPerInch -density 300 \"$jpg\" \"$png\"");
Adjusting the units & density will not alter the underlining image data, but updates meta info for rendering libraries. Important for vector to raster, but not very useful for raster to raster. To adjust the DPI of an image, use the -resample operation.
convert source.jpg -resample 300 out.png
You verify the DPI resolution with the following...
identify -format "%[resolution.x] %[resolution.y]\n" out.png
I'm wondering where the 72dpi is coming from. Assuming you are using X and some kind of Unix, ImageMagick defaults to using the screen resolution (72 dpi). I'm not sure what it does under OSX/XQuartz but it's likely similar. Is your screen resolution set to 72dpi (!?).
I'm with #emcconville #ikegami - just do this straight from ImageMagick on the commandline - passing the right options to be sure.
There are image manipulation modules that you can use from perl without having to resort to system commands as well such as Imager::Transformations, Image::Magick, and GD. Here's how to convert with GD.
perl -MGD -E 'my $imgjpg = GD::Image->newFromJpeg("img.jpg");
open my $imgpng, ">", "img.png" or die; print $imgpng $imgjpg->png();'
With most image manipulation packages the original resolution show be maintained during conversion - though some (including GD) will default to lower color depths (8 bit) unless passed a Truecolor flag.
e.g. GD::Image->newFromJpeg("img.jpg", 1);
I have raw NV12 YUV progressive Data and required to split each frame into images with even and odd fields (interlaced data).
If you want to do all the jobs manally:
Extract each frame from .yuv file
Depending on the format and resolution of your stream, caculate the size of one frame. Then, you can do the extration.
Split .yuv frame into .yuv field
Caculate the size of each line, and split the frame by odd/even line. Please take care of the uv line if the format is yuv420.
Covert .yuv field to .bmp image
If the format is not yuv444, then convert it to yuv444 first. Then, do the yuv to rgb convertion, and store the image into .bmp format.
With the help of ffmpeg and ImageMagick, it can also be done (more easier) by two steps (supposing that the resolution of frame is 1920x1080 and field is 1920x540) :
Convert YUV to Images
ffmpeg -s 1920x1080 -i input.yuv frame_%3d.bmp
-pix_fmt can be used to specify the format(pixel layout) of .yuv file.
Split Images to Odd/Even
convert frame_000.bmp -define sample:offset=25 -sample 100%x50% frame_000_top.bmp
convert frame_000.bmp -define sample:offset=75 -sample 100%x50% frame_000_bot.bmp
These two commands can be found in the last part of de-interlace a video frame.