У меня есть холст на моей веб-странице; Я создаю новые данные изображения в этом холсте, а затем модифицирую некоторый пиксель через массив myImgData.data []. Теперь я хотел бы масштабировать этот образ и увеличивать его. Я попытался масштабировать контекст, но изображение остается маленьким. Можно ли сделать это? Спасибо
Как масштабировать изображение в HTML-холсте?
Ответ 1
Вы можете нарисовать imageData на новом холсте, масштабировать исходный холст и затем нарисовать новый холст к оригинальному холсту.
Что-то вроде этого должно работать:
var imageData = context.getImageData(0, 0, 100, 100);
var newCanvas = $("<canvas>")
.attr("width", imageData.width)
.attr("height", imageData.height)[0];
newCanvas.getContext("2d").putImageData(imageData, 0, 0);
context.scale(1.5, 1.5);
context.drawImage(newCanvas, 0, 0);
Здесь функционирует демо http://jsfiddle.net/Hm2xq/2/.
Ответ 2
Мне нужно было сделать это без интерполяции, вызванной putImageData(), поэтому я сделал это, масштабируя данные изображения в новый, измененный размер объекта ImageData. Я не могу думать ни о каком другом времени, я думал, что использование 5 вложенных циклов было хорошей идеей:
function scaleImageData(imageData, scale) {
var scaled = c.createImageData(imageData.width * scale, imageData.height * scale);
for(var row = 0; row < imageData.height; row++) {
for(var col = 0; col < imageData.width; col++) {
var sourcePixel = [
imageData.data[(row * imageData.width + col) * 4 + 0],
imageData.data[(row * imageData.width + col) * 4 + 1],
imageData.data[(row * imageData.width + col) * 4 + 2],
imageData.data[(row * imageData.width + col) * 4 + 3]
];
for(var y = 0; y < scale; y++) {
var destRow = row * scale + y;
for(var x = 0; x < scale; x++) {
var destCol = col * scale + x;
for(var i = 0; i < 4; i++) {
scaled.data[(destRow * scaled.width + destCol) * 4 + i] =
sourcePixel[i];
}
}
}
}
}
return scaled;
}
Я надеюсь, что по крайней мере один другой программист может скопировать и вставить это в свой редактор, бормоча: "Там, но по благодати Бога идите".
Ответ 3
Вы можете масштабировать холст, используя метод drawImage.
context = canvas.getContext('2d');
context.drawImage( canvas, 0, 0, 2*canvas.width, 2*canvas.height );
Это уменьшит изображение, чтобы удвоить размер и сделать северо-западную часть его на холсте. Масштабирование достигается с помощью третьего и четвертого параметров метода drawImage, которые определяют результирующую ширину и высоту изображения.
См. документы на MDN https://developer.mozilla.org/en-US/docs/DOM/CanvasRenderingContext2D#drawImage%28%29
Ответ 4
Я знаю, что это старая тема, но так как люди, как это может показаться полезным, я добавляю мою оптимизацию к коду rodarmor:
function scaleImageData(imageData, scale) {
var scaled = ctx.createImageData(imageData.width * scale, imageData.height * scale);
var subLine = ctx.createImageData(scale, 1).data
for (var row = 0; row < imageData.height; row++) {
for (var col = 0; col < imageData.width; col++) {
var sourcePixel = imageData.data.subarray(
(row * imageData.width + col) * 4,
(row * imageData.width + col) * 4 + 4
);
for (var x = 0; x < scale; x++) subLine.set(sourcePixel, x*4)
for (var y = 0; y < scale; y++) {
var destRow = row * scale + y;
var destCol = col * scale;
scaled.data.set(subLine, (destRow * scaled.width + destCol) * 4)
}
}
}
return scaled;
}
Этот код использует меньше циклов и работает примерно в 30 раз быстрее. Например, при 100-кратном увеличении области 100 * 100 эти коды занимают 250 мс, а другая занимает больше 8 секунд.
Ответ 5
Ответ на@Castrohenge работает, но, как указывает Мухаммед Умер, после этого он помещает координаты мыши на исходном холсте. Если вы хотите сохранить возможность выполнения дополнительных масштабов (для обрезки и т.д.), Вам нужно использовать второй холст (для масштабирования), а затем извлекать данные изображения со второго холста и помещать их в исходный холст. Например:
function scaleImageData(imageData, scale){
var newCanvas = $("<canvas>")
.attr("width", imageData.width)
.attr("height", imageData.height)[0];
newCanvas.getContext("2d").putImageData(imageData, 0, 0);
// Second canvas, for scaling
var scaleCanvas = $("<canvas>")
.attr("width", canvas.width)
.attr("height", canvas.height)[0];
var scaleCtx = scaleCanvas.getContext("2d");
scaleCtx.scale(scale, scale);
scaleCtx.drawImage(newCanvas, 0, 0);
var scaledImageData = scaleCtx.getImageData(0, 0, scaleCanvas.width, scaleCanvas.height);
return scaledImageData;
}