Изменение размера холста P5 в соответствии с размером изображения - PullRequest
0 голосов
/ 23 мая 2018

Пожалуйста, посмотрите на следующий код P5.
Цель этого небольшого приложения - перетаскивать изображение на холст, изменяя его размер в соответствии с шириной и высотой «загруженного» изображения.

/**************************************************/
//GENERAL
var canvas;
//IMAGE
var img;//image
var imgW;//image width
var imgH;//image height
/**************************************************/
function setup(){
  canvas = createCanvas(710, 400);//initial canvas size
  canvas.drop(gotFile);
}
/**************************************************/
function draw(){
    background(0);
    if(img){
    image(img, 0, 0);
    imgW = img.width;
    imgH = img.height;
        if(imgW > 0 && imgH > 0){
            resizeCanvas(imgW, imgH);
        }
    }
    fill(255);
    text(imgW + ", " + imgH, 10, 10);
}
/**************************************************/
//
function gotFile(file){
  if (file.type === 'image') {
    img = createImg(file.data).hide();
  }
}
/**************************************************/
function mouseClicked(){
    if(img){
        if(imgW > 0 && imgH > 0){
            resizeCanvas(imgW, imgH);
        }
    }
}

Использование draw(): один раз изображениебыл загружен успешно (по крайней мере, отображая его), я назначаю его ширину и высоту для переменных imgW и imgH.Затем следует изменение размера холста ... что приводит к ошибке, размер холста совпадает с размером загруженного изображения (установлен на Developer Tools), но ничего не отображается.

Использование mouseClicked():При отключении изменения размера холста на draw() и нажатии на холст изменение размера происходит идеально, показывая изображение.

Приложение должно работать без щелчка, это должно быть автоматическое изменение (размер холста) после удаленияизображение.

ОБНОВЛЕНИЕ

Это то, что я вижу на консоли при сбросе Ошибка, полученная на консоли:

Uncaught RangeError: Maximum call stack size exceeded
    at Array.map (<anonymous>)
    at p5.Color._parseInputs (p5.js:44096)
    at new p5.Color (p5.js:43147)
    at p5.color (p5.js:42827)
    at p5.Renderer2D.background (p5.js:50315)
    at p5.background (p5.js:44288)
    at draw (sketch.js:21)
    at p5.redraw (p5.js:52435)
    at p5.resizeCanvas (p5.js:51826)
    at draw (sketch.js:30)

ОБНОВЛЕНИЕ 2

Вот как теперь выглядит код, вызывая resizeCanvas для метода drop:

/**************************************************/
//GENERAL
var canvas;
//IMAGE
var img;
var imgW;
var imgH;
var z;
/**************************************************/
function setup(){
  canvas = createCanvas(710, 400);
  canvas.drop(gotFile); 
}
/**************************************************/
function draw(){
    background(0);
    //
    if(img){
        imgUpdate();
    }
    //debug
    fill(255);
    text(imgW + ", " + imgH, 10, 10);
}
/**************************************************/
function gotFile(file){
  if (file.type === 'image') {
    img = createImg(file.data).hide();
  }
  while (!img) {

  }
  createP("Uploaded");

  if(img)
  {
    imgUpdate();
    resizeCanvas(imgW, imgH);
  }
}
/**************************************************/
function mouseClicked(){
    if(img)
    {
        if(imgW > 0 && imgH > 0)
        {
            resizeCanvas(imgW, imgH);
        }
    }
}
/**************************************************/
function imgUpdate()
{
    image(img, 0, 0);
    imgW = img.width;
    imgH = img.height;
}
/**************************************************/

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Проблема заключается в асинхронной загрузке данных изображения.Вы можете использовать метод loadImage () , воспользоваться обратным вызовом успеха и написать gotFile следующим образом:

function gotFile(file){
  if (file.type === 'image') {
    img = loadImage(file.data, 
                    function(){
                      imgUpdate();
                      resizeCanvas(imgW, imgH);
                    });
  }

  createP("Uploaded");
}
0 голосов
/ 23 мая 2018

Имейте в виду, что функция draw() вызывается 60 раз в секунду.Он также вызывается всякий раз, когда вы вызываете функцию resizeCanvas().

Вы звоните resizeCanvas(), который вызывает draw(), который вызывает resizeCanvas(), который вызывает draw(), пока в итоге вы не получите ошибку.

Чтобы это исправить, вам нужно перестать вызывать resizeCanvas() каждый кадр.Похоже, что вы, вероятно, можете вызвать его изнутри функции gotFile()?

Редактировать: После устранения этой проблемы ваша следующая проблема вызвана тем, что JavaScript загружает изображения асинхронно.Подумайте о том, что происходит в этой строке:

img = createImg(file.data).hide();

Файл createImg() берет URL-адрес и начинает загружать изображение в фоновом режиме, пока код продолжает выполняться.Затем вы используете img для изменения размера холста, но изображение на самом деле еще не загружено, поэтому ширина и высота не определены.Попробуйте распечатать некоторые значения в консоли, чтобы понять, что я имею в виду.

Чтобы устранить эту проблему, нужно подождать, пока изображение действительно загрузится.Я думаю, что вы пытаетесь сделать это с помощью вашего while цикла, но учтите, что ваш цикл не очень эффективен, потому что img всегда будет определен в первый раз.Вам нужно пойти на один уровень глубже и проверить ширину и высоту изображения перед его использованием.

Вы также можете использовать ссылку p5.File , чтобы проверить тип файла, прежде чем продолжить исделать что-то вроде отображения индикатора выполнения во время загрузки изображения.

...