// enlarge // James Brink, 6/30/2020 let can; // the canvas for the "original" image, reduced in size let enCan; // the canvas for the enlarged part of the image let x, y, w, h; // for rectangle in can let wr, hr; // size of the reduced picture let maxWr, maxHr; // max for upper image (excludes borders) let xx, yy, ww, hh; // part of original to be enlarged let we, he; // size of the enlarged picture let wo, ho; // size original picture let r; // ratio w to ww or h to hh let ratioWidthToHeight = 4/3; // assumed picture size ratio let marg = 10; let drawEnCan = true; let canvasWidth, canvasHeight; let img, img2; let imgOK = true; let minSlide, maxSlide; function preload() { img = loadImage("GrandCanyonBig.JPG"); } // preload function setup() { img2 = img; //upper reduced size image canvas canvasWidth = min(540, .75 * windowWidth); canvasHeight = (windowHeight - 100)/2; if (canvasHeight < .75 * canvasWidth) { canvasWidth = ratioWidthToHeight * canvasHeight; } else { canvasHeight = canvasWidth/ratioWidthToHeight; } can = createCanvasClass(canvasWidth + 2 * marg, canvasHeight + 2 * marg); can.parent("p5-left"); we = canvasWidth; // get dimensions of enlarged lower image he = 3 * we / 4; // always height = .75 * width (excludes border) enCan = createCanvasClass(we + 2 * marg, he + 2 * marg); enCan.parent("p5-right"); enCan.background("white"); setupImage(); can.drop(dropped); enCan.drop(dropped); slider = createSlider(0, 100, 100); slider.input(sliderChange); slider.parent("topText"); } // setup function draw() { can.background("silver"); // draw the "boundary rectangle over which the image is drawn can.fill("white"); can.rect(0, 0, wr + 2 * marg, hr + 2 * marg); // draw the image can.image(img, marg, marg, wr, hr) ; if (can.mouseIsPressed || drawEnCan) { if (!drawEnCan) { x = round(constrain(can.mouseX - marg, 0, wr - w)); y = round(constrain(can.mouseY - marg, 0, hr - h)); } drawEnCan = false; xx = x * wo / wr; yy = y * ho / hr; enCan.background("white"); enCan.image(img2, marg, marg, we, he, xx, yy, ww, hh); } // draw the enlargement rectangle if (w < maxWr + 5 && h < maxHr + 5) { // little slack for roundoff can.stroke("black"); can.fill(255, 0, 255, 50); can.rect(x + marg, y + marg, w, h); } // add Magnification value to upper image can.textSize(18); can.fill("black"); can.text("Magnification: " + round(100 * r) / 100, 15, 30); } // draw function sliderChange() { r = map(slider.value(), 0, 100, minSlide, maxSlide)/100; // update the rectangle setEnlargementRect(); drawEnCan = true; } // sliderChange function setupImage() { wo = img.width; // original image width and heigth ho = img.height; if (wo < we || ho < he) { alert("This image is quite small. The lower image is enlarged and might" + " be blurry. The slider is disabled. You may not be able to move" + " the enlargement panel."); } else if (wo < 1.5 * we || ho < 1.5 * he) { alert("This image is somewhat small and not much enlargement is" + " possible."); } maxWr = can.width - 2 * marg; maxHr = can.height - 2 * marg; if (wo/ho >= maxWr/maxHr) { // get dimensions of reduced size upper image wr = maxWr; // allow for 2 10px borders hr = round(wr * ho / wo); } else { hr = maxHr; wr = round(hr * wo / ho); print("2 " +wr + " x " + hr); } r = min(wo/wr, ho/hr) ; // calculate reduction ratio // these ratios should be the same setEnlargementRect(); // get limits on enlargement ratio - check for narrow shapes let ratio1 = max(we/wr,he/hr); let ratio2 = min(we/w, he/h); if (ratio1 > ratio2) { ratio2 = ratio1; } minSlide = 100 * max(ratio1); maxSlide = 100 * min(ratio2); } // setupImage function setEnlargementRect() { w = round(we/r); // width and height of little rectangle in upper image h = w/ratioWidthToHeight; if (w > wr) { w = wr; h = w/ratioWidthToHeight; } else if (h > hr) { h = hr; w = h * ratioWidthToHeight; } ww = w * wo / wr; // size of rectangle in the original image hh = ww/ratioWidthToHeight; ////////h * ho / hr; xx = .5 * (wo - ww); // location of rectangle yy = .5 * (ho - hh); // in the original image x = round(constrain(xx * wr / wo, 0, wr - w)); y = round(constrain(yy * hr / ho, 0, hr - h)); } // setEnlargementRect function dropped(file) { if (file.type == "image") { imgData = file.data; let div = document.getElementById("leftText"); let p = createP("Loaded file: " + file.name); p.parent(div); can.loadImage(file.data, imgA => { img = imgA; can.clear(); img2 = img; enCan.clear(); setupImage(); drawEnCan = true;}); } else { alert(file.name + " is not an image file"); } } // dropped