Image() не принимает ширину и высоту

#javascript #image

#javascript #изображение

Вопрос:

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

 loadImage(name, src, width, height) {
    return new Promise((resolve, reject) => {
        const image = new Image();
        this._Assets[name] = image;
        image.onload = () => resolve(name);
        image.onerror = () => reject(`failed to load ${name}`);
        image.src = src;
        if (width != void 0) image.width = width;
        if (height != void 0) image.height = height;
    });
}
 

Как вы можете видеть, я присваиваю изображению параметры ширины и высоты, но это не работает. Изображение имеет ширину и высоту в свойствах, однако само изображение отображается через context.drawimage с использованием naturalwidth и naturalheight . Однако, когда я пытаюсь назначить изображение уже после загрузки изображения. это выдает мне сообщение об ошибке: невозможно установить ширину свойства, но само изображение обрезается. Я попытался сразу передать параметры новому изображению (ширина, высота), но это ни к чему не привело.
Если мы попытаемся передать параметры в drawimage

 assets[`bg`].width
assets[`bg`].height
 

тогда все работает

Комментарии:

1. Попробуй image.style.width = width 'px';

2. также стоит проверить любые стили css

3. @Barmar Используя style, параметры устанавливаются на исходную высоту и ширину

4. @t3dodson Я не подключал никаких стилей.

5. @Fraybyl я почти уверен, что проблема в чем-то другом. Я не знаю, как вы присоединяете _Assets массив к dom. Я сделал аналогичный пример для вашего кода, и он работает. jsfiddle.net/c4opfn8a/2

Ответ №1:

Это нормально, CanvasRenderingContext2d.drawImage он вообще не будет смотреть на атрибуты width and height вашего HTMLImageElement, используя только параметры x и y, он будет использовать внутренние размеры исходного изображения.

Однако этот метод поставляется с несколькими различными сигнатурами, которые позволяют устанавливать разные размеры:

 const image = new Image();
image.src = "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
image.onload = e => {
  const ctx = document.querySelector( "canvas" ).getContext( "2d" );
  ctx.drawImage( image, 0, 0 ); // use intrinsic dimensions
  ctx.drawImage( image, 0, 0, 150, 150 ); // take the full source and resize to 150x150
  ctx.drawImage( image, 0, 0, 350, 350, 160, 0, 50, 50 ); // take the source rectangle at 0,0,350,350 and draw it in a 50x50 rectangle
} 
 <canvas id="canvas" width="500" height="500"></canvas> 

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


 (async () => {
  const blob = await fetch( "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png" )
    .then( (resp) => resp.blob() );
  const image = await createImageBitmap( blob, { resizeWidth: 150, resizeHeight: 150 } );
  const ctx = document.querySelector( "canvas" ).getContext( "2d" );
  ctx.drawImage( image, 0, 0 ); // resized
})().catch( console.error ); 
 <canvas id="canvas" width="500" height="500"></canvas> 

Комментарии:

1. Я понимаю и знаю это, но я хочу, чтобы изображения меняли свое разрешение на то, которое мне нужно сразу после загрузки.

2. Мы используем метод, как и ожидалось: передаем ваши размеры.