Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stretch images with no antialiasing

So I ran across this recently: http://www.nicalis.com/

And I was curious: Is there a way to do this sort of thing with smaller images? I mean, it's pixel art, and rather than using an image with each pixel quadrupled in size couldn't we stretch them with the code? So I started trying to make it happen.

I tried CSS, Javascript, and even HTML, none of which worked. They all blur up really badly (like this: http://jsfiddle.net/nUVJt/2/), which brings me to my question: Can you stretch an image in-browser without any antialiasing?

I'm open to any suggestions, whether it's using a canvas, jQuery, CSS3, or whatever.

Thanks for the help!

EDIT: There's a better way to do this now! A slightly less hackish way! Here's the magic:

.pixelated {     image-rendering: -moz-crisp-edges;     image-rendering: -o-crisp-edges;     image-rendering: -webkit-optimize-contrast;     -ms-interpolation-mode: nearest-neighbor;     image-rendering: pixelated; } 

And that'll stop the anti-aliasing in all the modern browsers. It'll even work in IE7-8, but not in 9, and I don't know of any way of doing it in 9, unfortunately (aside from the canvas hack outlined below). It's not even funny how much faster it is doing it this way than with JS. Here's more info on those: https://developer.mozilla.org/en-US/docs/CSS/Image-rendering

EDIT2: Because this isn't an official spec yet, it's not very reliable. Chrome and FF both seem to have stopped supporting it since I wrote the above (according to this article which was mentioned below), which is really annoying. We're probably going to have to wait a few more years before we really can start using this in CSS, which is really unfortunate.

FINAL EDIT: There is an official way to do this now! There's a new property called image-rendering. It's in the CSS3 spec. Support is super spotty right now, but Chrome just added support so before too long we’ll be able to just say image-rendering: pixelated; and it’ll work all the places (yaayy evergreen browsers!)

like image 351
Timothy Miller Avatar asked Dec 21 '11 22:12

Timothy Miller


People also ask

How do I resize an image without anti-aliasing?

There are free programs like Inkscape or payed programs like Adobe Illustrator. With these you will be able to make the graphic to a specific height/width then rasterize (the process of turning mathematically defined lines to pixels) the final to a jpeg or whatever file form you need.

Does anti-aliasing reduce image quality?

Supersample Anti-Aliasing (SSAA)It makes your GPU render games at a higher resolution, and then it down-samples the image. The higher resolution increases the number of pixels, making the image look sharper. But again, the downside is that it requires a high-end and powerful GPU with additional video memory.

How do I turn off anti-aliasing in Photoshop?

That's just how they work in PS. With the shape tool selected, check the tool options and on the left side you will see a dropdown that says Shape . Change that to Pixels and a new checkbox option ( anti-alias ) will appear.

What is image antialiasing?

In digital signal processing, spatial anti-aliasing is a technique for minimizing the distortion artifacts (aliasing) when representing a high-resolution image at a lower resolution. Anti-aliasing is used in digital photography, computer graphics, digital audio, and many other applications.


2 Answers

I've gotten this to work for canvas

var canvas = document.getElementById("canvas"),     context = canvas.getContext('2d'); context.webkitImageSmoothingEnabled = context.imageSmoothingEnabled = context.mozImageSmoothingEnabled = context.oImageSmoothingEnabled = false; 
like image 28
Leonard Meagher Avatar answered Oct 17 '22 05:10

Leonard Meagher


The Canvas documentation explicitly does not specify a scaling method - in my own tests it did indeed anti-alias the image quite badly in Firefox.

The code below copies pixel by pixel from a source image (which must be from the same Origin or from a Data URI) and scales it by the specified factor.

An extra off-screen canvas (src_canvas) is required to receive the original source image, and its image data is then copied pixel by pixel into an on-screen canvas.

var img = new Image(); img.src = ...; img.onload = function() {      var scale = 8;      var src_canvas = document.createElement('canvas');     src_canvas.width = this.width;     src_canvas.height = this.height;      var src_ctx = src_canvas.getContext('2d');     src_ctx.drawImage(this, 0, 0);     var src_data = src_ctx.getImageData(0, 0, this.width, this.height).data;      var dst_canvas = document.getElementById('canvas');     dst_canvas.width = this.width * scale;     dst_canvas.height = this.height * scale;     var dst_ctx = dst_canvas.getContext('2d');      var offset = 0;     for (var y = 0; y < this.height; ++y) {         for (var x = 0; x < this.width; ++x) {             var r = src_data[offset++];             var g = src_data[offset++];             var b = src_data[offset++];             var a = src_data[offset++] / 100.0;             dst_ctx.fillStyle = 'rgba(' + [r, g, b, a].join(',') + ')';             dst_ctx.fillRect(x * scale, y * scale, scale, scale);         }     } }; 

Working demo at http://jsfiddle.net/alnitak/LwJJR/

EDIT a more optimal demo is available at http://jsfiddle.net/alnitak/j8YTe/ that also uses a raw image data array for the destination canvas.

like image 154
Alnitak Avatar answered Oct 17 '22 05:10

Alnitak