Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 13.05.2019, 14:34
Аспирант
Отправить личное сообщение для korih Посмотреть профиль Найти все сообщения от korih
 
Регистрация: 02.06.2016
Сообщений: 36

проблема с canvas image
Добрый день уважаемые. столкнулся с проблемой на канвас. цель сделать простой кропер.
1)загруженное изображение скалируется под разрешение canvas (разрешение полотна 600х400)
2)на данное изображение накладывается черно-белый фильтр и блюр
3)создается второй слой этого же изображения, но уже цветно и обрезанное под нужное разрешение (разрешение можно динамически менять)
4) это слой можно передвигать по всему канвас-полотну и видеть какое изображение будет в результате на выходе
вот часть кода:
handleCanvas = () => {
        let { posX, posY, img} = this.state

        /*  
            img - загруженное изображение
            posX - координаты нового слоя с изобращением по Х
            posY - координаты нового слоя с изобращением по Y

        */

        let c=document.getElementById('canvas_t');
            if(c){
                //
                let MAX_WIDTH = 600;
                let MAX_HEIGHT = 400;
                let width = img.width;
                let height = img.height;

                if (width > height) {
                    if (width > MAX_WIDTH) {
                        height *= MAX_WIDTH / width;
                        width = MAX_WIDTH;
                    }
                } else {
                    if (height > MAX_HEIGHT) {
                        width *= MAX_HEIGHT / height;
                        height = MAX_HEIGHT;
                    }
                }
                //
                let ctx
                c.width = width
                c.height = height
                ctx = c.getContext('2d')
                ctx.clearRect(0, 0, 600, 400);
                ctx.filter = 'grayscale(100) blur(3px)'
                
                //рендерим фон изображения на полотне
                ctx.drawImage(img, 0, 0, width, height )
                

                //очищаем фильтр
                ctx.filter = 'grayscale(0) blur(0)'
                
                ctx.strokeRect(posX, posY, this.state.w, this.state.h)

                //рендерим новое изображение с позициями и указанным форматом
                ctx.drawImage(img , posX, posY,this.state.w,this.state.h, posX, posY, this.state.w,this.state.h)

                

                ctx.fillStyle = 'rgba(138, 196, 235, 0.7)'

                ctx.fillRect(posX + this.state.w - 5,posY + this.state.h - 5, 10,10)
            }      
    }


Суть проблемы:
редактируемый слой изображения не сходится с фоновым

Ответить с цитированием
  #2 (permalink)  
Старый 13.05.2019, 14:59
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,005

Самый простой способ - сделать clip на основе текущей выбранной рамки кропа и зарядить ctx.drawImage(img, 0, 0, width, height ) повторно - отрисуется только тот квадратик, который в клипе.

Набросок:
...
ctx.save();
ctx.beginPath();
ctx.rect(posX, posY, this.state.w, this.state.h);
ctx.clip();
ctx.drawImage(img, 0, 0, width, height );
ctx.restore();
...


Плюс этого способа - не придется морочить голову сдвигами и размерами (если картинка не сжимается в размерах и рисуется как есть, то всё просто, иначе надо правильно подобрать параметры для самой полной версии drawImage, что слегонца геморно. Хотя, впрочем, спозиционировать установленную рамку на реальную картинку всё равно придется, так что можно и сразу это делать)

Последний раз редактировалось Alexandroppolus, 13.05.2019 в 15:09.
Ответить с цитированием
  #3 (permalink)  
Старый 13.05.2019, 15:17
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,005

Кстати, картинка с размерами, к примеру, 600х500 неправильно посайзится в твоем кропе
Ответить с цитированием
  #4 (permalink)  
Старый 13.05.2019, 15:20
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

korih, когда рисуешь второе изображение, не учитываешь скалирование от первого.
Ответить с цитированием
  #5 (permalink)  
Старый 13.05.2019, 15:31
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,005

навскидку, без clip

let MAX_WIDTH = 600;
let MAX_HEIGHT = 400;
let width = img.width;
let height = img.height;
let ratio = 1;

if (width > MAX_WIDTH || height > MAX_HEIGHT) {
    ratio = Math.max(width / MAX_WIDTH, height / MAX_HEIGHT);
    width = width / ratio;
    height = height / ratio;
}

......

//рендерим новое изображение с позициями и указанным форматом
ctx.drawImage(img, posX * ratio, posY * ratio, this.state.w * ratio, this.state.h * ratio, 
        posX, posY, this.state.w, this.state.h);
Ответить с цитированием
  #6 (permalink)  
Старый 13.05.2019, 15:40
Аспирант
Отправить личное сообщение для korih Посмотреть профиль Найти все сообщения от korih
 
Регистрация: 02.06.2016
Сообщений: 36

Alexandroppolus, спасибо тебе большое, очень помог
Ответить с цитированием
  #7 (permalink)  
Старый 13.05.2019, 16:16
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Alexandroppolus, korih,
const MAX_WIDTH = 600;
const MAX_HEIGHT = 400;
let width = img.width;
let height = img.height;
const ρ = 1 / Math.min(MAX_WIDTH / width, MAX_HEIGHT / height, 1);

width  /= ρ;
height /= ρ;

// ......

// дорисовываем новое изображение с позициями и указанным форматом
ctx.drawImage(img, posX * ρ, posY * ρ, this.state.w * ρ, this.state.h * ρ, 
        posX, posY, this.state.w, this.state.h);
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Повтор фото (getUserMedia(),HTML5 Canvas) aspex Элементы интерфейса 1 27.12.2014 16:46
Canvas картинка с обесцвечиванием. cheba Общие вопросы Javascript 9 31.05.2013 09:13
canvas prerendering Simulator Общие вопросы Javascript 1 18.01.2013 09:28
html5, Canvas, KineticJS, cvg, google chrome N3K Библиотеки/Тулкиты/Фреймворки 0 20.07.2012 12:43
Canvas: drawImage проблема. Jurasmi jQuery 3 11.01.2010 14:57