2013-08-31 3 views
11

У меня есть небольшое изображение, которое я отрисовка на холсте, как это:Изменение размера холст изображения без размытости его

ctx.drawImage(img, 0, 0, img.width*2, img.height*2); 

Я хотел бы, чтобы это показать резкое преобразованное изображение (4 одинаковых пикселей для каждого пиксель изображения). Однако этот код (в Chrome 29 на Mac) создает размытое изображение. В условиях Photoshop это похоже на использование повторной выборки «Bicubic» вместо «Nearest Neighbor».

В ситуации, когда это было бы полезно (например, ретро-игра). Возможно ли создать резкое изображение с повышенным разрешением или мне нужно иметь отдельный файл изображения для каждого размера изображения на сервере?

+0

лучший способ сделать это, чтобы иметь отдельные изображения для каждого размера (самое быстрое, хорошее качество), другой способ - иметь самый большой, затем изменить размер их на ходу (минимальное хранилище, хорошее качество). – slash197

+0

@ slash197 Если я уменьшился, у него будет такое же размытие. – JJJollyjim

+1

не должно быть размытым, сохраняете ли вы соотношение сторон? – slash197

ответ

18

Просто отключить антиалиасинг холст для изображений - к сожалению, это свойство еще Vendor приставкой так вот варианты:

context.webkitImageSmoothingEnabled = false; 
context.mozImageSmoothingEnabled = false; 
context.imageSmoothingEnabled = false; /// future 

затем нарисовать изображение.

При необходимости для более старых версий и браузеров, которые не реализованы в этом же, вы можете использовать CSS вместо:

canvas { 
    image-rendering: optimizeSpeed;    // Older versions of FF 
    image-rendering: -moz-crisp-edges;   // FF 6.0+ 
    image-rendering: -webkit-optimize-contrast; // Webkit (non standard naming) 
    image-rendering: -o-crisp-edges;   // OS X & Windows Opera (12.02+) 
    image-rendering: crisp-edges;    // Possible future browsers. 
    -ms-interpolation-mode: nearest-neighbor; // IE (non standard naming) 
} 

ONLINE TEST HERE

+1

Фантастическое, гораздо лучшее (и более элегантное) решение, чем масштабирование больших файлов или 'getImageData'. – JJJollyjim

+2

Непрефикс 'context.imageSmoothingEnabled' работает в Chrome как минимум по версии 33. – Luke

1

Проверить эту скрипку: http://jsfiddle.net/yPFjg/

Он загружает изображение в холст, а затем создает копию измененного и использует в качестве спрайта.

С помощью нескольких модификаций вы можете реализовать загрузчик изображений, который изменяет размеры изображений на лету.

var ctx = document.getElementById('canvas1').getContext('2d'); 
var img = new Image(); 
var original = document.createElement("canvas"); 
var scaled = document.createElement("canvas"); 

img.onload = function() { 
    var oc = original.getContext('2d'); 
    var sc = scaled.getContext('2d'); 
    oc.canvas.width = oc.canvas.height = 16; 
    sc.canvas.width = sc.canvas.height = 32; 
    oc.drawImage(this, 0, 0);  
    var od = oc.getImageData(0,0,16,16); 
    var sd = sc.getImageData(0,0,32,32); 
    for (var x=0; x<32; x++) { 
     for (var y=0; y<32; y++) { 
      for (var c=0; c<4; c++) {   
       // you can improve these calculations, I let them so for clarity   
       sd.data[(y*32+x)*4+c] = od.data[((y>>1)*16+(x>>1))*4+c]; 
      } 
     } 
    } 
    sc.putImageData(sd, 0, 0); 
    ctx.drawImage(scaled, 0, 0);  
} 

img.src = document.getElementById('sprite').src; 

Некоторые примечания о getImageData: он возвращает объект с массивом. Массив имеет высоту * ширину * 4 размера. Цветовые компоненты хранятся в порядке RGBA (красный, зеленый, синий, альфа, 8 бит каждого значения).

+0

Это не работает для меня в Firefox (ошибок в консоли JS нет). http://i.imgur.com/DDqlxTS.png – JJJollyjim

+0

исправлено для FF. Я изменил создание образа (строка 2) –

Смежные вопросы