Мне нужно скопировать регион из одного холста в другой размер для этого региона.Область может быть больше в одном или обоих измерениях, чем элемент холста, содержащий ее.Я использую большую область для улучшения качества изображения на целевом холсте.
Проблема в том, что ctx.drawImage (), использующий холст src, приводит к отсечению изображения из src в холст dest.
Вот некоторые методы, которые мы попробовали.
Мы масштабировали область исходного холста, мы хотим сделать его меньше ширины / высоты холстаэлемент, преобразованный в верхний левый угол исходного холста, а затем использовал drawImage () с определенными координатами области, чтобы скопировать данные непосредственно на целевой холст.В результате получается в лучшем случае размытое изображение, чем меньше экран, тем меньше холст и размытость результата.
Мы пытались toDataURL, это на самом деле работает и правильно показывает данные изображенияэто не обязательно показывает на самом элементе холста.Тем не менее, это невероятно медленно ... Я пытался использовать 'image / jpeg' и понижать качество до 0,2-0,3, но производительность вызывает значительное заикание.
Мы пробовали ctx.getImageData (), конвертируя ImageData в BitmapImage и рисуя его на холсте.Это эффективно, но, к сожалению, приводит к проблеме отсечения.Честно говоря, drawImage () может использовать это под капотом, если честно ...
const ctx = destCanvas.getContext('2d');
if (!ctx) {
throw new Error('Failed to get context for static canvas, BUG!');
}
// Store state of srcCanvas viewport to be restored later & reset the viewport
const originalViewport = srcCanvas.viewportTransform;
const scaledViewport = [
TEX_MULT,
0,
0,
TEX_MULT,
0,
0
];
srcCanvas.viewportTransform = scaledViewport;
// Disable any elements that shouldn't be visible on the static canvas.
if (srcCanvas.overlayImage) {
srcCanvas.overlayImage.visible = false;
}
const hiddenForRender: fabric.Object[] = [];
srcCanvas.getObjects().forEach((obj: fabric.Object) => {
if (obj.excludeFromExport && obj.visible) {
obj.visible = false;
hiddenForRender.push(obj);
}
});
// Store resized viewport for image calculations and rerender srcCanvas
const renderViewport = srcCanvas.viewportTransform;
srcCanvas.renderAll();
// Copy the active canvas to the static canvas
const srcCtx = srcCanvas.getContext();
const rawImageData = srcCtx.getImageData(
0,
0,
destCanvas.width * renderViewport[0] * window.devicePixelRatio,
destCanvas.height * renderViewport[3] * window.devicePixelRatio
);
createImageBitmap(rawImageData).then(function(imgBitmap: ImageBitmap) {
ctx.drawImage(
imgBitmap,
0,
0,
destCanvas.width * renderViewport[0] * window.devicePixelRatio,
destCanvas.height * renderViewport[3] * window.devicePixelRatio,
0,
0,
destCanvas.width * TEX_MULT,
destCanvas.height * TEX_MULT
);
});
Я еще не нашел технику, которая работает так же хорошо, как getImageData или drawImage (srcCanvas), но позволяет указать область, которая выходит за пределы элемента canvas, не видя отсечения на холсте назначения.Неужели это невозможно?