I have a large png image (950x500px) which I have been scaling down using CSS to 500px wide (and 263 high). Before putting this webpage online I decided to scale the image using GIMP as scaling images with CSS is bad practice. However there is a noticeable reduction in image quality when I scale the image using GIMP rather than CSS in Google Chrome even though both images are png and have identical dimensions. I have tried using all four compression methods offered by GIMP (None, Linear, Cubic and Sinc (Lanczos3)) and none of them match the image quality given by Google Chrome.
What compression method does Google Chrome use to give such high-quality image scaling and how can I achieve this offline?
You may get the answer to your question here: How web browsers resize images
Chrome seems to be using several algorithms depending on the scaling factor:
With a very slight downscale (557 to 555 pixels), Chrome uses the same
linear interpolation as when upscaling. (The fact that this graph is
disconnected is an artifact of the way ResampleScope works, and has
nothing to do with Chrome.)
But look what happens if we downscale just a bit more, to 543 pixels:
[…] We get a completely different result: clearly a 3-lobed Lanczos
filter. Chrome’s strategy may be to use Lanczos when reducing an image
by more than 2.5%.
If you have to do it yourself (to get more control on the result), Cubic is usually the best bet scaling up and Sinc (Lanczos3) for scaling down.
If you scale the image yourself, you know how it will look on all browsers.
Note: There are more and more computers equipped with high resolution displays (around 4 times the pixel density of a classic display). You may want to check how images look on those computers. There is a high chance they are scaled up by the browser.
This is a very old question, but I was struggling with an image resize in Gimp yesterday. When I compared the image resized in Gimp with the image automatically resized in Chrome (and Safari), there was a visible difference.
I was resizing a PNG logo from 89x127 to 69x101 and the text blurred after the resize in Gimp no matter which interpolation I chose.
Thanks to the comment above saying that ImageMagick gave a better result when resizing an image, I found this article: Efficient Image Resizing With ImageMagick
The command from the article, despite its claims to be indistinguishable from Photoshop, did not produce a result that matched Chrome, however one of the commenters added a command that did create an image that produced the closest result (barring the resize my friend did in Photoshop):
convert SOURCE_IMAGE -resize OUTPUT_WIDTH -quality 90 -unsharp 0x0.55+0.55+0.008 OUTPUT_IMAGE
I think the trick lies mainly in the sharpening. I've tried different settings and can't exactly match Chrome, but this came pretty darn close.
For completeness, here is the command from the article. Please read the article for a full explanation of how it works:
mogrify -path OUTPUT_PATH -filter Triangle -define filter:support=2 -thumbnail OUTPUT_WIDTH -unsharp 0.25x0.25+8+0.065 -dither None -posterize 136 -quality 82 -define jpeg:fancy-upsampling=off -define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=1 -define png:exclude-chunk=all -interlace none -colorspace sRGB -strip INPUT_PATH
Related
I have a sprite sheet that i use as div background . The dimensions are :
Width: 105920
Height: 240 .
It's a monochrome png file with size of 620kb , so i assume size is not the problem here .
When i try to use it as a background-image: url("spritesheet.png"); Firefox throws an error saying "Image corrupt or truncated" . Chrome does not show any error message , but the image is not shown .
If i resize the width of the image with gimp to 10,000 , everything is ok . but obviously i cannot use it as intended any more .
Are there any restrictions for maximum allowed image size in CSS ? Am i doing something wrong ?
According to the answer to this question, your image is too big for Safari/iOS to handle. Other browsers probably have similar limitations, as you have found with Firefox. The file-size of 620kb is acceptable, but the dimensions of the image (over 25million pixels) is a little too much to handle.
That said, even if browsers could show your image, I would very strongly advise against using an image of those dimensions. One uses sprites for performance reasons, but an image that size will incur a massive performance penalty... you'd be shooting yourself in the foot.
Not a solution to your problem, merely a comment. The advantages of using sprite-sheets may be lost or much reduced when you orient them horizontally. This causes a problem with cache-misses.
Imagine you had a 10x10 pix sprite. To load the portion of the your image that contains it, you need to load (numPixels = sprite_height * src_width).
In your case, this would be 10 x 105920 pixels = 1,059,200 pixels! - Just to cache 100 pixels worth of image.
The best way to orient a sprite sheet is vertically. You use the same equation to determine the number of pixels that must be loaded, but get a very different result. A result that is now small enough to fit in the small(est), fast(est) cache.
In this case: 10 x 240 pixels = 2400 pixels. - Again, overkill for just 100 pixels, but a superior solution than the previous example gives.
Changing the orientation of the sheet from horizontal to vertical results in a reduction of the size of the memory needed to cache this sprite of 441 times. Not exactly something I would characterize as insignificant.
The effect of making this change will be most apparent when repeatedly drawing the same sprite or sprites that are located near to one another in the sprite-sheet.
Given that the browser works with tru-colour images on the screen, it doesn't seem unreasonable to think that for performance reasons, the browser would convert your monochrome image to one compatible with the remainder of the display - one that has 24 bits/pixel, albeit with (relatively) little variation in value.
If indeed the image was converted to 24bit, well, the memory requirements would be huge
105920 * 240 * 3 = 76262400bytes. Yes!! That's 72.73 megabytes!! Add another 1/3 if its converted to an rgba(32 bit) image.
So, I've got two suggestions.
Orient your images vertically
Use several sprite sheets.
I have an 40px by 20px image with 72 Pixels / Inch.
I would like to create a Retina display version.
What should I do? Double the size? Change the resolution?
And in which format should I save it? PNG? JPG? ...
I am using this image on a web site ...
In your image editor, double the size of your image to 80px by 40px.
In your markup set the width to 40 and height to 20.
<img src="example.png" width="40" height="20" />
You should save as png if you need transparency or the image is line art. Save photographs as jpg.
My answer is convert your image into SVG
Do you have Illustrator? If so save your image as SVG (and have a png as a fallback if you want).
<img src="images/logo.svg" alt="" />
<img src="images/logo.png" alt="" />
As long as you use Modernzr which can work to get svg friendly in most browsers.
You can see it here how it's done:
http://toddmotto.com/mastering-svg-use-for-a-retina-web-fallbacks-with-png-script/
Hope it helps :)
A retina display image (or high-density display image) is double the pixel size of a standard image - its scaling factor is 2.0. This means that yes, for your 40x20 pixel image, you will need to make an 80x40 pixel version (that is then displayed at double pixel density on screen). The format doesn't matter as much, both PNG and JPG will work fine (PNG will not degrade in quality with compression, but the file size will be larger than JPG).
However, the problem with high-density display images is that they take up more bandwidth, and are unnecessary for devices that don't have the high resolution or Retina displays. This means more data transferred over the network, inconveniencing mobile users and those with limited data transfer caps.
One solution is to use something like Retina.js. It's an open-source javascript client script that will automatically load the retina-sized image from your server and swap it in-place for the low-density version, if it exists. It follows Apple's standard for naming high-resolution images - #2x, so you can have HTML code like this:
<img src="/images/my_image.jpg" />
and the script will search your server also for /images/my_image#2x.jpg. If it exists, it will load it and swap it in-place without having to worry about messing with CSS.
Generally as of this writing there are two types of retina displays, hence you should create an image for each type.
For a 2× device, you would need to produce twice the logical pixels' width and height with a resolution of 144 pixels per inch (72 ppi ✕ 2).
For a 3× device, you would need three times the logical pixels with a resolution of 216 pixels per inch (72 ppi ✕ 3).
Examples of 2× devices are the MacBook Pro (released in 2012-2019) and most iPhone since the iPhone 4. Examples of 3×
devices are the iPhone 6 Plus, and the iPhone X. However the iPhone Xr is a 2× device.
Hence for your case you would need images in 80 px ✕ 40 px and 120 px ✕ 60 px for 2× and 3× devices respectively.
Retina displays are not dependent on the specific bitmap image format. You can use the original image format. For websites, you should use JPG for photographs and PNG for line-art graphics saved as bitmaps.
You should not just blindly enlarge images otherwise this would create a blurred results – it would no better than if you don't include any high-resolution versions in the first place. Either obtain the original higher-resolution version of the images (typically from vector graphic source) and downscale them or use a machine-learning based image enhancement solution such as Bigger Picture to "convert" your image into a higher resolution.
Photoshop gives you a couple options for resizing an image. For instance if the image is iPhone size you can increase the image size by 200%. Photoshop gives you a couple options for resampling of the image. Bicubic, bilinear and etc. This will remake the image at a higher resolution and interpolate the missing pixels. Hope this helps.
This is a really interesting article showing a nice option for dealing with high res images:
http://blog.netvlies.nl/design-interactie/retina-revolution/
Basically, it's saying that, if you make the image quite large (width and height) but then save it at quite low quality, it still comes out very sharp on retina displays. It means that you can use the one same image on all devices, and that the file size is very low, too, which is an extra bonus. You can set the width and height of the image in your CSS and/or HTML to set it to the visual dimensions you desire.
This article blew me away, and is my go-to approach for dealing with both retina-friendly and bandwidth-friendly images. Win, win.
You can use CSS opacity option.
This will give you an transparent look of your image based upon the value you set to opacity.
Try learning opacity: http://www.w3schools.com/css/css_image_transparency.asp
Is it possible to achieve Retina-quality CSS masking using -webkit-mask-box-image? In this particular case, I am trying to round the corners of an element (border-radius is not performant enough):
.element {
-webkit-mask-box-image: url('mask.png') 12 12 12 12 stretch stretch;
}
The mask image is twice the size that it needs to be (6 is used in place of 12 for non-retina screens).
The mask is correctly positioned, but the corner rounding is not Retina-smooth.
I see three solutions, here:
Suck it up and deal with border-radius, because you can't be getting that much lag on modern machines. Plus, only Safari and Chrome (and minor webkit-based browsers like RockMelt,
Yandex, et cetera) use -webkit-mask, so unless you're making a Chrome app, you're losing a lot of your audience (currently about 54.25%) to browser incompatibility, not to mention that it requires the user to download an image just to see rounded corners.
Webkit uses image smoothing within its scaling algorithm, so simply provide a gigantic mask image and let it do its one-time scaling on load. This has the inherent downside of taking much longer to download and some time after to scale, but, again, it's a one-time thing until the cache clears.
Instead of using a PNG, use an SVG. The whole point of Scalable Vector Graphics is that they're infinitely scalable and don't lose quality at any resolution or size. For more on how to make a SVG file, see http://www.w3.org/Graphics/SVG/
Let me start off by stating that I realize the arguments against doing CSS Sprites for large images. I even asked a question about why that could be considered a bad idea (and added an answer of my own). Now that we've had that talk...
I'm going to be making a large CSS Sprite-map. For the process of making this sprite-map, it behooves me to know what (if any) limit exists for the height and/or width of a sprite image in order for browsers to properly process it.
The ultimate reason behind this question is a debate over whether to lay out the sprite images in a grid or in a single row/column. For example: is it necessary or beneficial to do 4000 x 3000 instead of 400 x 30000?
Edit: The sticking point here isn't about what size images can be, but rather what size browsers can process for sprites. Given the lack of detail thus far, I'm moving forward with generating the single-large-column sprite. I'll post details of my experiences as an answer once that is complete.
Sometimes it's more of a matter of download time. Since browsers can use multiple connections to download files, a huge image can take longer to download than a few smaller ones.
If your image is so big that it's slowing down page load maybe it's time to consider several smaller sprite images.
Direct-X 9 has a size limit if 4096 pixels, so any Internet Explorer filters applied to these elements will crop them at 4096 pixels.
See: IE display transparency bug on height > 4096px?
In practice, this seems to work with no problems in Firefox 5+, Chrome, and IE7+ for a sprite image of 400x16560.
The potential issues of IE's directx rendering engine failing on images over 4096px do not create problems in IE7 or beyond; we have no method or need to test IE6 for our current project.
The one place that we experienced problems with really large spritemaps is on mobile platforms. Android devices handle them reasonably well, but iOS devices break down pretty badly, and in a strange way: They shrink the image down to fit within the dimensions they accept. So our CSS works perfectly for a small spritemap, but with no changes except increasing the physical dimensions of the spritemap image, the sprited images begin to show four times as much of the spritemap in the same html entity, with exactly the same CSS.
There is a limit in version 1.0 that is upgraded in v1.1 But still there is a limit for dimensions:
In accord with version 1.1, the scope of the 31-bit limit on chunk
lengths and image dimensions has been extended to apply to all
four-byte unsigned integers. The value -231 is not allowed in signed
integers.
Source
A funny limit is IE6.0 fails to display PNG images of 4097 or 4098 bytes in size!
But these limits are very huge in compare to what we're using in web pages.
I have an zoomable image in the website. When the image is zoomed out to a large extend it appears very SHARP and ugly.
I tried using image-rendering : opimizequality, optimizespeed CSS but did not work.
Is there any other way out.
Thanks
According to image-rendering on MDC, image-rendering is currently only supported in Firefox 3.6. A similar property, -ms-interpolation-mode, is available for IE7 and IE8. Other browsers don't seem to have this feature (yet).
As latze mentioned, your best bet is to edit the image itself, scaling it to the level you need. I'm not sure, but you may try using <canvas> to perform the interpolation you desire.
I would simply edit the picture instead of the CSS.
Try making the picture slightly larger step by step while you make sure the picture doesn't (as we call it in danish, not sure if it correct english) "pixelate".
This can be done in various image editing programs from The Gimp-shop to Photoshop.
Images aren't meant to be resized that much. Think about an image as a graph where each pixel is a single square in the graph. If you stretch the image out, you're essentially making the pixels stretch out. Some programs try to fill in these pixels with what they think would fit there, others just make the pixel bigger, and others just fill in the surrounding areas with the same pixels to give it a sort of glowish effect. Resizing images down, while it tends to work better, also creates the same effect, because you're just chopping off pixels instead of adding them. Most programs that I've seen will squish pixels together, combining whichever colors were in those pixels. If you have a high detail image, then chopping off pixels is going to make it look horrible. There are no really safe ways to determine which pixels need to be retained to keep the overall image in tact. Most websites that have zoom features have a much larger image which has been resized down and they let you zoom to view the details of the larger image. Some even get separate images of the massive detailed one and the smaller preview one.