iOS: Convert PNG to HEIF/HEIC + Alpha without quality loss - ios

For a project I'm currently working on, I'm trying to convert a bunch of PNG images to HEIF/HEIC. These images will be used in Xcode's .xcassets, which will then be "compiled" into a .car file.
Compiling the PNGs (~150 total files) results in ~40 MB of Assets.car, which is why I'm trying to convert them to HEIF/HEIC in the first place. I've tried various solutions, such as ImageMagick, "Export as" in GIMP, biodranik/HEIF, libheif's heif-enc, exporting a PNG as 8-bit or 16-bit in Photoshop and doing everything all over again. But everything results in the .heic file being "broken" on iOS. The first image shows the best output I've got so far, but still fringes around the edges. The white rounded rectangle on the right is iOS' Face ID padlock.
The second image is (I think) a 16-bit PNG converted to HEIC using libheif#1.8.0, upgraded through Homebrew. Lossless quality preset, 10-bit output. heif-enc complained about the color space being converted from RGB to YCbCr, stating even though you specified lossless compression, there will be differences because of the color conversion
Is there any way to properly convert PNG files to HEIF/HEIC without such quality loss? Please don't suggest online services to convert files, as I'd like to keep total control of my files.

Note: To get lossless encoding, you need this set of options. Try :-
-L switch encoder to lossless mode
-p chroma=444 switch off color subsampling
--matrix_coefficients=0 encode in RGB color-space

Related

Is webp format more efficient than JPEG?

I am trying to compress and resize DSLR camera photos. But my observation so far is that webp has noticeable degraded quality when webp file size is about 30% smaller than JPEG.
Command used to generate webp using imagemagick:
convert 1.JPG -strip -quality 80 -resize 800 -define
webp:method=6 1.webp
My goal is to get webp format that is at least 20% samller file size than JPEG while having virtually no difference in quality between JPEG and webp.
Is this achievable or again there is no such thing as free lunch?
Update Since the time of the original posting, I've discovered that using Google's cwebp compressor shows dramatically improved compression over ImageMagik 6.7.8, which is what powered my initial tests. This is especially true for images with transparency when compared to PNGs. Files using the mac version of the webp command (which uses cwebp under the hood) are about 1/4 of the size of the same file compressed with ImageMagik, and do provide a significant performance boost.
According to Google, "WebP typically acheives an average of 30% more compression than JPG" (source) with similar visual quality to a JPG. However, as you suggest, there in never such a thing as a free lunch.
Quality
Quality is largely a subjective measure, but keep in mind that you're comparing a file compressed at quality 80 with a file that doesn't have that level of compression (at least, this is what I understand from your question). Just running the default conversion without specifying a lower quality may give you slightly smaller files without loss of visible quality. 20% smaller might be a bit much of an ask, though, but it may be achievable for certain images.
convert 1.JPG 1.webp # do not specify quality
Size
In practice, it depends a lot on your settings and your source images. For example, I recently ran this command on all jpg images in a folder on a website "in the wild":
convert filename.jpg -quality 80 -strip -define webp:lossless=false -define webp:method=6 filename.webp
The convert command on this particular server is powered by ImageMagick 6.7.8. Some files were dramatically smaller compared to the original JPGs, while others were actually larger. Overall, after running that command, the total file sizes of all JPG images was 49MB, while the total file size of all WebP images was 29MB. That's a pretty good savings, however, when I ran ImageMagick's JPG compression, it was even better:
convert filename.jpg -sampling-factor 4:2:0 -strip -quality 80 -interlace JPEG filename-new.jpg;
The size of all new jpgs in the directory was 21MB. Both are set to compress at quality 80, but the jpg compression appears to be better. This may have to do with some compression already on my set of test images and how that interacts with the WebP conversion process.
As I found, file sizes can even grow, usually if you are converting between lossy and lossless images. On the FAQ page linked above, Google claims: "this is mainly due to the colorspace difference (YUV420 vs ARGB) and the conversion between these."
tl;dr: In the wild, it may or may not improve file size depending on the type of images, if/how the source file was compressed, and what quality you set for the WebP. Visible degradation is harder thing to measure, but try setting a higher quality, or without specifying a quality at all.
Just to add a side-comment to #Pwpwpw's excellent answer, webp is a good PNG replacement, but not great as a JPG replacement.
It beats PNG because it has better lossless compression algorithm than libpng, and it has the great feature of allowing different compression settings for different channels. You can do lossless on the alpha but lossy on the RGB, for example, which is fantastic for overlays.
Against JPG it does less well. It uses the VP8 codec for lossy, which is only somewhat better than JPG.
I would take a look at HEIC. It uses the much more modern h.265 for lossy compression and typically beats JPG by a factor of two at the same quality. It's the format Apple are using by default on iOS now.
libheif have a nice demo here:
https://strukturag.github.io/libheif/
That's libheif, compiled to javascript and running in your browser. You can upload .heic to it and download as jpg. libheif have some basic command-line tools to encode and decode images.
It does sadly have some patent issues, you might need to be a little cautious.
update Looking further out, the current hope is AVIF: it's the same container format as HEIC (called HEIF, confusingly), but swaps the problematic h.265 compressor for AV1. AV1 is roughly equivalent to h.265, but is patent-free.
update for 2022 AVIF seems to be too slow to be practical, so now hope rests on JXL. It's fast, patent free, supports HDR, transparency, etc., and compression is as good as HEIC. Chrome has support, though it's behind a flag for now.
You are re-encoding lossy compressed jpeg; if you have access to the original raw files you should use them as master. Currently you are compressing noise (and other artefacts) introduced by the jpeg encoder so the WebP codec does not have access to the same information that was already lost at the jpeg encoding. Of course it will look worse.
In other words; you should encode the original image data, if possible. I'm aware that some cameras and equipment only outputs HEIC / JPEG and not RAW so you might be out of options - the best thing to do is to keep the JPEGs as JPEGs.
Just did a quick test with a high-res JPG from my DSLR camera converting to a 410x800 background picture for mobile using Photoshop CC 2020 (and the WebPShop plugin).
Lossless:
PNG 100%: 680 KB
JPG 12 (max): 428 KB
WEBP 100%: 537 KB
50% quality:
JPG 6 (50%): 119KB
WEBP 50%: 45KB
At 50% JPG has more detail, but quite comparable quality.
0 quality:
JPG 0 (min): 51KB
WEBP 0%: 6KB
At 0% WEBP is horrible. But imagine the lowest quality JPG, and that's bad image quality and WEBP definitely beats it at 50%, while still being smaller in file size. So for me.. that's free lunch.

PNG Compression Not Reducing the size of images

I have certain png files. They are of size approx 1MB. I tried several command but they didn't work for me. Any suggestions. One is as below :
"C:\\Program Files\\ImageMagick-6.9.9-Q16\\mogrify.exe" -depth 8 -format png -define PNG:compression-strategy=2 -define PNG:compression-filter=0 test.png
Thanks,
As pointed out by #fmw42 in comments, your image may already be optimized. Also, #Mark's comment regarding reducing colors is true.
But apart from this, the important thing to know is that "there is no ideal command". You will have to figure out bit depth in your color channels and reduce them. There will always be a trade-off between reducing colors and quality you wish to pick.
Apart from that, there can also be other methods that you can use:
If opacity of PNG is fully opaque, you can strip alpha channel as it
makes no sense in that case. This can give you some file size savings.
If the image is visibly grayscale and still color type is
true-color, true-color-alpha or indexed-color, you can make significant savings by saving the image with a grayscale color space.
Retry optimizing PNG files using adaptive delta filtering and LZ77 Optimizations. This can be done easily using "optipng". But if the image is already optimized enough, this won't provide significant file sizes reduction. Moreover, choice of filtering depends upon png bit depths, so you would have to look up and understand PNG compression from various documentation available online regarding PNG compression.

How to get the PDF from the Cytoscape graph without blurring the image?

I'm able to get the JPG and PNG images from the Cytoscape graph, but when converting them into PDF using jsPDF, the image shrinks and is blurry on zoom-in.
Is there a way the image or graph can be converted to PDF without blurring?
It seems to me like you need to learn the difference between bitmap formats and vector formats.
Bitmap formats like PNG, GIF, BMP and JPEG do not support limitless zooming because they are made of small squares, called pixels.
Vector formats like PDF, SVG and EPS support limitless zooming without blurriness because they are made of geometrical shapes (though PDF can include bitmaps).
So you can convert between bitmap formats without problems (though you may get compression artifacts when using JPEG) but you cannot directly go from vector to bitmap and vice versa.
If you convert a vector image to bitmap, you need to rasterize it to a specific resolution.
If you convert a bitmap image to a vector image, you could use some advanced algorithms to guess the shape behind the pixels, but there is almost never enough information for this to work perfectly.
If you convert a bitmap image to PDF, the tool you are using may just embed the bitmap in the PDF. Now the PDF editor may let you zoom, but the image will get blurry.
The only way to get a real vector PDF is by having the application, in this case Cytoscape, export PDF directly, not converting it afterwards.
You wrote Cytoscape cannot do this but I am reading the manual of version 3.7.0 and it says you can export directly to PDF using "File → Export as Image..." and then selecting "PDF". Maybe at the time you posted this question, this version wasn't released yet.
P.S.: As noted by #ideogram you are using Cytoscape.js and not Cytoscape, so you can use the cytoscape-svg NPM package to export as SVG, which is a vector format, which you can then convert to PDF without getting any blurriness.

Reading 16-bit grayscale png using chunky_png

I'm trying to use chunky_png for reading PNG image in Ruby on Rails. the library seems to work fine reading 8-bit PNG image. However, what I actually have is 16-bit grayscale PNG image and I want to retriev pixel brightness value of certain points. All of my attempts on retrieving pixel value always end-up with 8-bit rgba format.
Is there any way to read 16-bit brightness value from grayscale png image using chunky_png? Or should I give up and use some other tools that can do this job instead?
Because of how ChunkyPNG stores color values internally, it doesn't support more than 8 bit colors per channel. It automatically converts channels to 8 bit values when it encounters higher values.
So, this is impossible now, and would require some significant rewrites of the codebase to make this possible (but pull requests are accepted! :)

imagemagick jpeg conversion

guys , can anyone explain me why when im converting my jpeg into new file with command line:
convert -quality 80 file.jpg file2.jpg
File size is 20Kb
But if i open this file with Gimp and just save is as file2.jpg with quality 80, i have 10Kb size.
The quality scales used by imagemagick and GIMP are probably different. JPEG is a fairly complex format, and it has more parameters than one simple "quality" setting. For example, the type of chroma sub-sampling (4:2:0 vs 4:2:2, etc).
Here's what the GIMP documentation says about this:
The JPEG algorithm is quite complex, and involves a bewildering number of options, whose meaning is beyond the scope of this documentation. Unless you are a JPEG expert, the Quality parameter is probably the only one you will need to adjust.
This is likely to be true for other applications (such as PhotoShop, etc) as well.
Play around with some of the other parameters in both GIMP and imageMagick and it is likely that you will get similar results. If you post your image, then people may be more inclined to play around with it.
convert -quality 80 -type palette -strip -depth 8 file.jpg file2.jpg
This solve the problem and the file size is very similar to gimp or photoshop.

Resources