#javascript #canvas #html5-canvas
#javascript #холст #html5-холст
Вопрос:
Я пытаюсь изменить размер изображения с помощью canvas. Моя цель — создать изображение размером A x B размером M x N без изменения пропорций, например, CSS contain. Например, если исходное изображение имеет размер 1000×1000, а конечное — 400×300, оно должно отрезать кусок размером 100 пикселей внизу, и это должно соответствовать 250 пикселям в исходном изображении.
Мой код приведен ниже:
const canvas = document.createElement('canvas');
const img = new Image();
img.src = promotedImage;
const FINAL_WIDTH = 400;
const FINAL_HEIGHT = 250;
const width = img.width;
const height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height, 0, 0, FINAL_WIDTH, FINAL_HEIGHT);
const finalImage = b64toFile(canvas.toDataURL("image/jpg"));
Однако это не работает, как я хочу. Очевидно, я неправильно использую drawImage. Для меня, если копирует источник в пункт назначения без изменения размера.
Это потому, что мне нужно изменить размер (изменить размеры) холста перед рисованием? Пожалуйста, сообщите.
Я также пробовал что-то вроде загрузки изображений Mozilla. Он даже масштабирует изображение, но не обрезает. Кроме того, он увеличивает размер исходного квадрата до меньшей целевой стороны, вместо того, чтобы обрезать его.
Комментарии:
1. Обычно размер холста по умолчанию составляет 300×150. Да, вам нужно будет установить атрибуты
width
иheight
, чтобы изменить это. (Это не то же самоеwidth
height
, что стили и CSS.) Обратите внимание, что это может быть только частью вашей проблемы.2. Спасибо. Полезно знать.
Ответ №1:
Установка источника изображения выполняется асинхронно, может быть очень быстрой, но часто недостаточно быстрой, чтобы успевать за все еще работающим кодом. Как правило, чтобы они работали надежно, вы onload
сначала устанавливаете обработчик, а затем устанавливаете src
. Элемент canvas по умолчанию равен 300×150, поэтому его размер также должен быть изменен. (Холст подчиняется CORS. .crossOrigin = ''
делает нас анонимными, а imgur имеет разрешительную политику CORS. В противном случае мы не смогли бы преобразовать холст в изображение, используя стороннее изображение в этом фрагменте.)
const MAX_WIDTH = 400;
const MAX_HEIGHT = 300;
const img = new Image();
img.crossOrigin = '';
img.onload = () => {
const wRatio = MAX_WIDTH / img.width;
const hRatio = MAX_HEIGHT / img.height;
var width, height;
if(wRatio > hRatio) {
width = MAX_WIDTH;
height = wRatio * img.height;
}
else {
width = hRatio * img.width;
height = MAX_HEIGHT;
}
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height);
//const finalImage = b64toFile(canvas.toDataURL("image/jpg"));
const imgElement = document.createElement('img');
imgElement.src = canvas.toDataURL('image/jpg');
document.body.appendChild(imgElement);
};
img.src = 'https://i.imgur.com/TMeawxt.jpeg';
img { border: 1px solid red; }
Комментарии:
1. Однако ваш пример НЕ сохраняет пропорции. Это растягивает изображение.
2. Этот помещается внутри изображения, но тогда сбоку есть свободное / неиспользуемое пространство. Я думаю, это может зависеть от размеров. Однако замена знака
<
для>
меня устраняет проблему. Все еще требуется немного больше тестирования. Спасибо.3. @IgorShmukler Если холст не имеет точно такого же соотношения сторон, что и исходное изображение, всегда будут либо пробелы, либо обрезка. Я внес коррективы, чтобы соотношение сторон холста соответствовало соотношению сторон изображения. Параметр
<
/>
определяет, должен ли размер соответствовать или закрывать.