Как растянуть изображения без сглаживания
Итак, я натолкнулся на это недавно: http://www.nicalis.com/index.php
И мне было любопытно: есть ли способ сделать такие вещи с меньшими изображениями? Я имею в виду, это пиксельное искусство, и вместо того, чтобы использовать изображение с каждым пикселем в четыре раза по размеру, мы не могли бы растянуть их с помощью кода? Поэтому я начал пытаться это сделать.
Я пробовал CSS, Javascript и даже HTML, ни один из которых не работал. Они все сильно размываются (например: http://jsfiddle.net/nUVJt/2/), что подводит меня к моему вопросу: вы можете растянуть изображение в браузере без любое сглаживание?
Я открыт для любых предложений, будь то использование холста, jQuery, CSS3 и т.д.
Спасибо за помощь!
EDIT: Там лучший способ сделать это сейчас! Немного менее хакерский путь! Здесь волшебство:
.pixelated {
image-rendering: -moz-crisp-edges;
image-rendering: -o-crisp-edges;
image-rendering: -webkit-optimize-contrast;
-ms-interpolation-mode: nearest-neighbor;
image-rendering: pixelated;
}
И это остановит сглаживание во всех современных браузерах. Это даже будет работать в IE7-8, но не в 9, и я не знаю, как это сделать в 9, к сожалению (кроме холста, описанного ниже).
Это даже не смешно, насколько быстрее он делает это так, как с JS. Здесь более подробная информация о них: https://developer.mozilla.org/en-US/docs/CSS/Image-rendering
EDIT2: Поскольку это еще не официальная спецификация, она не очень надежна. Chrome и FF оба, похоже, перестали поддерживать его, так как я написал выше (согласно спецификация CSS3. Поддержка super spotty прямо сейчас, но Chrome просто добавила поддержку поэтому перед слишком длинным успехом можно просто сказать image-rendering: pixelated;
и itll работать во всех местах (yaayy вечнозеленые браузеры!)
Ответы
Ответ 1
В документации Canvas явно не указан метод масштабирования - в моих собственных тестах он действительно сильно исказил изображение в Firefox.
Нижеприведенный код копирует пиксель из исходного изображения (который должен быть из одного и того же Origin или из URI данных) и масштабирует его по указанному коэффициенту.
Для получения исходного исходного изображения требуется дополнительный экранный экран (src_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);
}
}
};
Рабочая демонстрация на http://jsfiddle.net/alnitak/LwJJR/
EDIT более оптимальная демонстрация доступна в http://jsfiddle.net/alnitak/j8YTe/, которая также использует массив данных необработанного изображения для место назначения.
Ответ 2
Я получил это для работы на холсте
var canvas = document.getElementById("canvas"),
context = canvas.getContext('2d');
context.webkitImageSmoothingEnabled = context.imageSmoothingEnabled = context.mozImageSmoothingEnabled = context.oImageSmoothingEnabled = false;
Ответ 3
Единственный способ, которым я могу думать, - это создать холст. Вы можете попробовать просто рисовать изображение на холсте, а затем масштабировать холст - я думаю, что вы не получите сглаживания таким образом. Если вы все еще это делаете, вы можете попробовать либо масштабировать изображение в обратном вызове, либо если это не сработает, вы можете использовать getImageData
и putImageData
для масштабирования изображения "вручную"
update: первый метод работает: http://jsfiddle.net/nUVJt/3/
Ответ 4
Неа. Однако браузер делает это, но делает это, и вы не можете контролировать алгоритмы масштабирования.
Тем не менее, я уверен, что есть решение на основе холста, которое вы могли бы сделать, но это, вероятно, связано с копированием пикселей из исходного изображения и стратегическим введением их в холст. Это было бы сложно, но возможно (и медленно).
Ответ 5
im не уверен, но, возможно, вы можете использовать imagedata. попробуйте эту функцию.
function imageToImageData(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
return ctx.getImageData(0, 0, canvas.width, canvas.height);
}