JPEG: Dimensions versus Compression - compression

Pretty simple but specific question here:
I'm not entirely familiar with the JPEG standard for compressing images. Does it create a better (that being, smaller file size at a similar quality) image when the X dimension (width) is very large and the Y dimension (height) is very small, vice versa, or when the two are nearly equal?
The practical use I have for this is CSS sprites. If a website were to consist of hundreds of CSS sprites, it would be ideal to minimize the size of the sprite file to assist users on slower internet and also to reduce server load. If the JPEG standard operates really well on a single horizontal line, but moving vertically requires a lot more complexity, it would make sense for an image of 100 16x16 CSS sprites to be 1600x16.
On the other hand if the JPEG standard has a lot of complexity working horizontally but moves from row to row easily, you could make a smaller file or have higher quality by making the image 16x1600.
If the best compression occurs when the image is a perfect square, you would want the final image to be 160x160

The MPEG/JPEG blocking mechanism would (very slightly) favor an image size that is an exact multiple of the compression block size in each dimension. However, beyond that, the format won't care if the blocks are vertical or horizontal.
So, the direct answer to your question would be "square is as good as anything", as long as your sprites divide easily into a JPEG compression block (just make sure they are 8, 16, 24 or 32 pixels wide and you'll be fine).
However, I would go a bit further and say that for "most" spites, you are going to have a smaller image size, and clearer resolution if you have the initial master image be GIF instead of JPG, even more so if you can use a reduced color palette. Consider why would you need JPG at all for "hundreds of sprites".

It looks like JPEG's compression ratio isn't affected by image dimensions. However, it looks like your dimensions should be multiples of 8 but in all your examples you had multiples of 16 so you should be fine there.
http://en.wikipedia.org/wiki/JPEG#JPEG_codec_example
If I remember correctly, PNG (being lossless) operates much better when the same color appears in a horizontal stretch rather than a vertical stretch. Why are you making your sprites JPEG? If they are of a limited color-set (which is likely if you have 16x16 sprites, animated or not), PNG might actually yield better filesizes with perfect image quality.

Related

Different Launch Screen Image or Background Image Sizes for iOS devices

I read some of those website links that explain about exporting different image sizes for iOS device. But I don't really understand of those explaining. (May be I am not good at in English language.)
I found these dimension for launch screen. Please let me clarify my understanding to you guys.
So, when I create an image, I must create a larger size(#3x) firstly and should export that image into smaller sizes (#2x, #1x). Am I right?
For example, I create 1242x2208px (3x) image and scale to 2x,3x and save.
My questions are that;
1) I draw images in Photoshop CS6.For any size of images, the Resolution is still 75px. isn't it?
So, for 1242x2208px(3x) size , the resolution is 75px and then I decrease the size. The image will small and does it get blurry appearance?
2) Does image elements (heart image in my example image)need to make to be large in smaller device(1x) to get the clear looks? Or
3) If we don't need to modify image elements or may be some texts of font size to be large or small, can we get the high resolution of image appearance in 1x? I'm afraid that if we scale to smaller(1x), it would be blur and not good in looks because we are still in 75 resolutions.
4) Does it need to make to fit the image elements to image size? I found this video https://www.youtube.com/watch?v=WOnczJSsMqk . In this video, he crops the white space and export into #1x, #2x and #3x. So, the size of #3x is not the image size from Apple official Guideline website. I don't know clearly this.
5) If we type the text (font size-90pt) in #3x image, then it will automatically changes to 60pt in #1x image. right?
But in this link https://www.smashingmagazine.com/2015/05/retina-design-in-photoshop/#font-size , he wrote that
a text box with the font set to 16 pixels. But #2x this is 32 pixels,
and #3x it’s 48 pixels!
Not ideal, is it, having to constantly multiply by two or three? I
don’t know about you, but I could do without the constant math. When I
design, I want to know that 16 pixels is 16 pixels!
So, the text should be 16 px in any size of image 1x,2x or 3x or not?
6) These image sizes are for launch screen, isn't it? But, if I create an image for background of Login screen, then is it the same concept and save as these sizes of image ?
7) Above image size dimension is correct or not? But, in this https://developer.apple.com/ios/human-interface-guidelines/graphics/launch-screen/ website, the sizes are a little bit different.
Now, I'm trying to create a design for login background image. So, I was finding the sizes before I draw. But, after reading many articles of image sizes in Retina device, I've confused and got many questions in my mind.
That's why I write down my questions like this and I would like to say sorry that my question is long and make you feel not easy to understand.
Sorry again for my poor English.
I hope anyone would help me to answer all my questions in steps.Thanks for reading till the end. :)
You are asking way to much here. First off, you do not work in pixels. You work in points. These are 2 different units of measurements. On a 1x scale 1 point = 1x1 pixel, on a 2x scale 1 point = 2x2 pixel, and on a 3x scale, 1 point = 3x3 pixels.
Now when it comes to how to scale, people claim that you start big and you got small for best quality. This is simply not true. It all depends on the actual image as to how it will scale. So your goal is to find what works best for the image. I would recommend starting off from big to small, but if it doesn't work out as nice as you like, go small to big, then try a different scaling method.
I personally do not rely 100% on automation, I like to tweak all 3 sizes manually until the images are perfect, which makes sprite-kit really tough to work with in this department because I have to design my graphics in a way that counter act the hardware scaling. Bottom line is at the end of the day, do what is best for your app within your budget constraints.
Now when it comes to font sizes, again you are working in points, not pixels. Whoever told you that you need to multiply has no understanding of how retina display works. So when you do 16pt font, the system will automatically pick 32pt and 48pt. (But if you read it it will still say 16pt)
Try not to over think this matter, it is really simple to understand. The entire point of retina display is to provide a sharper image while maintaining the same experience, and it does this by offering more granularity in the way pixels are displayed. Each individual pixel is very very tiny, which makes it hard to see with your eyes. Instead they are companions to other pixels, so that when your eyes put the 2 pixels together, you get a better looking image that could not be produced by using a single colored pixel. When you work on your apps, you want to keep this in mind. This is why it stinks for new people to get into development. Everybody should start with the iphone 2g, then adapt their app to iphone 4. They will get a clear understanding of what retina is built for.

How to manipulate large images in Firemonkey?

Does Firemonkey have an image manipulation library? Right now I'm doing everything with Canvases and it sucks.
I have a program which currently loads the image into a TBitmap, performs its operations, and then saves the TBitmap object out to a file.
The TBitmap interface however is not ideal. Among the problems...
It silently scales down images which are larger than 8k pixels in any dimension, losing resolution on large .png files
It scales the image whenever there are clipping issues with DrawBitmap which is undesirable (I'd much rather it clip the output or just crash)
Rotating bitmaps is very hard to predict the output of and may scale the image.
I want a better option than canvas methods for image manipulation. I see there are units under Vcl.Imaging, but I can't find anything similar under the FMX units.
The operations I'm really looking for are just drawing lines, text, zooming, rotating, blitting to the display, saving, and loading.

How to compress sprite sheets?

I am making a game with a large number of sprite sheets in cocos2d-x. There are too many characters and effects, and each of them use a sequence of frames. The apk file is larger than 400mb. So I have to compress those images.
In fact, each frame in a sequence only has a little difference compares with others. So I wonder if there is a tool to compress a sequence of frames instead of just putting them into a sprite sheet? (Armature animation can help but the effects cannot be regarded as an armature.)
For example, there is an effect including 10 png files and the size of each file is 1mb. If I use TexturePacker to make them into a sprite sheet, I will have a big png file of 8mb and a plist file of 100kb. The total size is 8.1mb. But if I can compress them using the differences between frames, maybe I will get a png file of 1mb and 9 files of 100kb for reproducing the other 9 png files during loading. This method only requires 1.9mb size in disk. And if I can convert them to pvrtc format, the memory required in runtime can also be reduced.
By the way, I am now trying to convert .bmp to .pvr during game loading. Is there any lib for converting to pvr?
Thanks! :)
If you have lots of textures to convert to pvr, i suggest you get PowerVR tools from www.imgtec.com. It comes with GUI and CLI variants. PVRTexToolCLI did the job for me , i scripted a massive conversion job. Free to download, free to use, you must register on their site.
I just tested it, it converts many formats to pvr (bmp and png included).
Before you go there (the massive batch job), i suggest you experiment with some variants. PVR is (generally) fat on disk, fast to load, and equivalent to other formats in RAM ... RAM requirements is essentially dictated by the number of pixels, and the amount of bits you encode for each pixel. You can get some interesting disk size with pvr, depending on the output format and number of bits you use ... but it may be lossy, and you could get artefacts that are visible. So experiment with limited sample before deciding to go full bore.
The first place I would look at, even before any conversion, is your animations. Since you are using TP, it can detect duplicate frames and alias N frames to a single frame on the texture. For example, my design team provide me all 'walk/stance' animations with 5 pictures, but 8 frames! The plist contains frame aliases for the missing textures. In all my stances, frame 8 is the same as frame 2, so the texture only contains frame 2, but the plist artificially produces a frame8 that crops the image of frame 2.
The other place i would look at is to use 16 bits. This will favour bundle size, memory requirement at runtime, and load speed. Use RGBA565 for textures with no transparency, or RGBA5551 for animations , for examples. Once again, try a few to make certain you get acceptable rendering.
have fun :)

Can't find logic behind png file sizes

I'm saving a large number of small png files for use in a game on a phone, so space is at a premium.
I'm trying to figure out the logic behind the file sizes so I can save things most efficiently, but even after using pngcrush the sizes are totally inconsistent.
I saved a 1x1 image and it takes 3kb. I have another 23x21 image which takes only 2kb. I have two images which are almost the same size, but one takes 6kb and the other takes 13kb. I doubled the image height and copied one image into the empty space of the other and saved that. The combined image is only 11kb!
Why is a 1x1 image larger than a 23x21 image? Why can I combine a 13kb image and a 6kb image and get an 11kb image?
Here are the images I'm talking about (there's a 1x1 pixel in between the 1st and second images. It's difficult to see, so I'll just give the URL: http://g42.org/temp/png/1x1.png):
example http://g42.org/temp/png/hat.png
example http://g42.org/temp/png/1x1.png
example http://g42.org/temp/png/helmet1.png
example http://g42.org/temp/png/helmet2.png
example http://g42.org/temp/png/helmet1_2.png
It's not a compression thing, the problem with the 1x1 image is that it has metadata (added by Photoshop, it seems), a color profile (iCCP chunk). If you look inside the binary, its' the data between the strings "iCCP" and "IDAT", it could be removed and you get a 69 bytes file.
If you reopen and save the file most image viewers (xnview), or use pngcrush, you can strip that chunk. : See it here : http://i.stack.imgur.com/fmOdA.png
And regarding the helmet images: besides other informational chunks (imageReady ads some informational text, as you can see), the difference is due to different formats: the two-helmets is a paletted image (8bits per pixel), the single helmet is a RGB with alpha (32bits per pixel)
PNG compression is based on the same algorithm as zlib and is highly sensitive to the data that is being compressed so you won't see a consistent relationship between image size and file size. In the case of the combined image, it is still bigger than the smaller image and given the similarity of the two halves of the image, the compressor was probably able to reuse a lot of the Huffman tree. I don't know enough about the algorithm to say for certain how it ended up smaller than the other half.
As long as you are not seeing oddities like the 1x1 image, which you seem to have figured out in the comments, I don't think this will make a lot of sense without extensive study of image compression.
There is a great utility called pngcrush
http://pmt.sourceforge.net/pngcrush/
Compressing to PNG is a rather difficult task - there are lost of assumptions and strategies to try - do we create a palette, or are we better off without it?
PNGcrush essentially bruteforces 100+ different compression strategies, while at the same time trimming useless tags and sections.
PNG has several sub-formats: 24-bit with or without alpha, 8-bit (includes alpha), grayscale, etc. which use different amount of bytes per pixel and have different "compressibility".
Plus PNG supports several compression tricks (filters and gzip settings) which affect how well image data is compressed.
On top of that PNG can contain metadata, which sometimes can be pretty large, like some embedded color profiles.
ImageAlpha converts images to the most space-efficient PNG8+alpha variant.
ImageOptim removes junk metadata and finds best compression parameters.
With a combination of those two your images can be reduced by 30-50%.

How do I enlarge a picture so that it is 300 DPI?

The accepted answer to the question C++ Library for image recognition: images containing words to string recommended that you:
Upsize/Downsize your input image to 300 DPI.
How would I do this... I was under the impression that DPI was for monitors, not image formats.
I think the more accurate term here is resampling. You want a pixel resolution high enough to support accurate OCR. Font size (e.g. in points) is typically measured in units of length, not pixels. Since 72 points = 1 inch, we need 300/72 pixels-per-point for a resolution of 300 dpi ("pixels-per-inch"). That means a typical 12-point font has a height (or more accurately, base-line to base-line distance in single-spaced text) of 50 pixels.
Ideally, your source documents should be scanned at an appropriate resolution for the given font size, so that the font in the image is about 50 pixels high. If the resolution is too high/low, you can easily resample the image using a graphics program (e.g. GIMP). You can also do this programmatically through a graphics library, such as ImageMagick which has interfaces for many programming languages.
DPI makes sense whenever you're relating an image in pixels to a physical device with a picture size. In the case of OCR, it usually means the resolution of the scan, i.e. how many pixels will you get for each inch of your scan. A 12-point font is meant to be printed at 12/72 inches per line, and an upper-case character might fill about 80% of that; thus it would be approximately 40 pixels tall when scanned at 300 DPI.
Many image formats have a DPI recorded in them. If the image was scanned, this should be the exact setting from the scanner. If it came from a digital camera, it always says 72 DPI, which is a default value mandated by the EXIF specification; this is because a camera can't know the original size of the image. When you create an image with an imaging program, you might have the opportunity to set the DPI to any arbitrary value. This is a convenience for you to specify how you want the final image to be used, and has no bearing on the detail contained in the image.
Here's a previous question that asks the details of resizing an image:
How do I do high quality scaling of a image?
OCR software is typically designed to work with "normal" font sizes. From an image point of view, this means that it will be looking for letters perhaps around the 30 to 100 pixel height range. Images of much higher resolution would produce letters that appear much too large for the OCR software to process efficiently. Similarly, images of lower resolution would not provide enough pixels for the software to recognise letters.
"How would I do this... I was under the impression that dpi was for monitors, not image formats."
DPI stands for dots per inch. What does it have to do with monitors? Well, we have a pixel made of three RGB subpixels. The higher the DPI, the more details you cram into that space.
DPI is a useful measurement for displays and prints but nothing useful... in fact, nothing for image formats themselves.
The reason for DPI being tagged inside some formats is to instruct the devices to display at that resolution but from what I understand, virtually all ignore that instruction and does its best to optimize the image for a particular output.
You can change 72 dpi to 1 dpi or 6000 dpi in an image format and it won't make a difference whatsoever on a monitor. "Upsize/downsize to 300 dpi" makes no sense. Resampling does not change DPI either. Try it in Photoshop, uncheck "Resample" when changing the DPI and you'll see no difference whatsoever. It will NOT get bigger or smaller.
DPI is totally meaningless for image formats, IMO.
If your goal is OCR, DPI makes sense as the number of dots in your image for each inch in the original scanned document. If your dpi is too low, the information is gone forever, and even bicubic interpolation is not going to to a brilliant job recovering it. If your dpi is too high, it's easy to throw away bits.
To get the job done; I'm a big fan of the netpbm/pbmplus toolset; the tool to start with is pnmscale, although if you've got a bitmap you want to consider related tools such as pbmreduce.