Как я могу обрезать область изображения с помощью JavaScript?

Как я могу обрезать область изображения с помощью JavaScript? Как я читал, я должен использовать холст, чтобы проецировать на него изображение.

С помощью следующего кода я вырезаю область изображения, но размер области вырезания не соответствует указанному.

  var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');
      var imageObj = new Image();

      imageObj.onload = function() {
        // draw cropped image
        var sourceX = 0;
        var sourceY = 0;
        var sourceWidth = 500;
        var sourceHeight = 150;
        var destWidth = sourceWidth;
        var destHeight = sourceHeight;
        var destX = canvas.width / 2 - destWidth / 2;
        var destY = canvas.height / 2 - destHeight / 2;

        context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
     

      };
      imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
    <canvas id = "myCanvas" style = "border:1px solid red"></canvas>

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

моя основная проблема в том, что канвас не подстраивается под размер обрезанного изображения и финальные height(sourceHeight) и width(sourceWidth) они не те что я указал

Как я могу это исправить?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
0
251
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам нужно будет сообщить canvas размер изображения, которое вы пытаетесь отобразить, чтобы убедиться, что canvas имеет размер desiredWith;

Однако размер вашего примера изображения составляет 438 × 300, что затрудняет обрезку до 500 пикселей.

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.src = 'https://placehold.it/700x700';
imageObj.onload = function() {

    const desiredWidth = 500;
    const desiredHeight = 150;
    
    canvas.width = desiredWidth;
    canvas.height = desiredHeight;

    context.drawImage(imageObj, 0, 0, desiredWidth, desiredHeight, 0, 0, desiredWidth, desiredHeight);
    
    console.info(canvas.width, canvas.height);
};
<canvas id = "myCanvas" style = "border:1px solid red"></canvas>

Спасибо! но размер сгенерированного холста не составляет 500 пикселей по ширине...

yavg 10.12.2020 16:15

Пожалуйста, смотрите мое редактирование @yavg, причина, по которой холст не был желаемого размера, можно исправить, установив пиксели.

0stone0 10.12.2020 16:27
Ответ принят как подходящий

Проблема

Ваша исходная «ширина» равна ширине изображения.

Решение

При использовании ctx.drawImage с 9 аргументами думайте об этом как о вырезании и вставке.

Вы хотите «вырезать» контур красным цветом и «вставить» его в новое место по центру. Вы хотите «вырезать» полностью до половины пути источника. Таким образом, вам нужно выбрать весь путь до середины изображения.

Я также предлагаю, возможно, изменить имя переменной с «источника» на «обрезку» (cropX, cropWidth и т. д.), чтобы лучше отразить ее назначение, поскольку на самом деле это уже не ширина «источника».

Если вы хотите, чтобы изображение заполнило весь холст, «вставьте» его с шириной и высотой холста (0,0)

context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, canvas.width, canvas.height);

Код

...
var context = canvas.getContext('2d');
    var imageObj = new Image();

    imageObj.onload = function() {
        // crop from 0,0, to 250,150
        var cropX = 0;
        var cropY = 0;
        var cropWidth = 250;
        var cropHeight = 150;

        //resize our canvas to match the size of the cropped area
        canvas.style.width = cropWidth;
        canvas.style.height = cropHeight;

        //fill canvas with cropped image
        context.drawImage(imageObj, cropX, cropY, cropWidth, cropHeight, 0, 0, canvas.width, canvas.height);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
...

я просто хочу, чтобы серый цвет занимал 100% обрезанного изображения. width 500px и «высота 150 пикселей».

yavg 10.12.2020 16:25

Вы хотите, чтобы обрезанное изображение заполнило холст?

Octal 10.12.2020 16:28

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

yavg 10.12.2020 16:33

Хм, я очень смущен тем, что вам нужно. Не могли бы вы изменить размер холста? Или это то, с чем вам нужна помощь?

Octal 10.12.2020 16:34

Итак, вы делаете викторину на что-то? Это довольно аккуратно! Но этот снимок экрана выглядел так, как будто это был ваш код, проверяющий ответ пользователя. Я не уверен, как это должно помочь мне понять, что вам нужно при рендеринге изображения...

Octal 10.12.2020 16:45

Ах, кажется, я понимаю, на изображении, которое вы указали в своем вопросе - справа - у вас есть небольшой фрагмент обрезанного результата. Вы хотите, чтобы это изображение было целым холстом?

Octal 10.12.2020 16:47

да! Я хочу чтобы. вырезать куски холста, где изображение не содержится

yavg 10.12.2020 16:55

Спасибо друг! в настоящее время ваш код дает мне ошибку «Uncaught TypeError: невозможно прочитать свойство« drawImage »неопределенного» окончательный вопрос, возможно ли преобразовать обрезанное изображение в base64?

yavg 10.12.2020 17:15

По поводу первого пункта. Убедитесь, что вы правильно выбираете контекст. Это означает, что контекст не определен, возможно, есть опечатка в идентификаторе холста или в конструкции объекта контекста. И для вашего второго пункта: попробуйте это

Octal 10.12.2020 17:17

Я надеюсь не беспокоить вас, но я разместил ваш код здесь, и если он работает, я также попытался поставить код для получения изображения в base64 jsfiddle.net/edkq9175

yavg 10.12.2020 17:30

Без проблем. Прошу прощения за задержку ответа. Во-первых, это не работает, потому что вы заменили весь свой код моим кодом. Я хотел, чтобы вы взяли соответствующий код и заменили им свой. Я отредактировал его, чтобы, надеюсь, сделать его более очевидным. Что касается base64, то этот вопрос немного отошел от темы, но, похоже, он работает, когда вы правильно используете мой код. jsfiddle.net/OctalDeveloper/rx84ebsn

Octal 10.12.2020 18:38

Другие вопросы по теме