Reputation: 878
I'm using drawImage
function with the same image but i got diffrent results when the source is img element vs when the source is canvas(with the same size as original image).
this is the code
async function draw(src) {
const mainCanvas = document.getElementById("cnv");
const ctx = mainCanvas.getContext("2d");
let img = document.getElementById("img");
let w = img.width;
let h = img.height;
if (src == "cnv") {
const newCnv = document.createElement("canvas");
newCnv.width = w;
newCnv.height = h;
const newCtx = newCnv.getContext("2d");
//just to be sure we dont touch the original image data
newCtx.imageSmoothingEnabled = false;
// i tested it with all function overloads and still the same
newCtx.drawImage(img, 0, 0, w, h, 0, 0, w, h);
img = newCnv;
}
let destW = 850;
const pxr = window.devicePixelRatio;
let destH = (destW * h) / w;
mainCanvas.style.width = destW + "px";
mainCanvas.style.height = destH + "px";
destW *= pxr;
destH *= pxr;
mainCanvas.width = destW;
mainCanvas.height = destH;
ctx.imageSmoothingQuality = "high";
ctx.drawImage(img, 0, 0, destW, destH);
}
<img
id="img"
style="display: none"
src="https://work.otzar.org/example.png"
/>
<button onclick="draw('img')">drawImage from img</button>
<button onclick="draw('cnv')">drawImage from canvas</button>
<br />
<canvas id="cnv"> </canvas>
i know when you use drawImage
its does some work like for example downscale when the dest size is lower. but here the newCnv
is the same as the original image so i dont understand why js need to do somestuff othar than just put the pixels data in the canvas.
Upvotes: 1
Views: 543
Reputation: 136638
The culprit is imageSmothingQuality = "high"
, I already faced it before, even with ImageBitmaps.
Different sources will get different results with their algo, even two JPEG <img> will have very different quality depending on the compression of the image.
You did well opening that issue.
Note that in my tests then I had the best looking results with imageSmothingQuality = "medium"
, which also doesn't suffer from this bug.
async function draw(src) {
const mainCanvas = document.getElementById("cnv");
const ctx = mainCanvas.getContext("2d");
let img = document.getElementById("img");
let w = img.width;
let h = img.height;
if (src == "cnv") {
const newCnv = document.createElement("canvas");
newCnv.width = w;
newCnv.height = h;
const newCtx = newCnv.getContext("2d");
//just to be sure we dont touch the original image data
newCtx.imageSmoothingEnabled = false;
// i tested it with all function overloads and still the same
newCtx.drawImage(img, 0, 0, w, h, 0, 0, w, h);
img = newCnv;
}
let destW = 850;
const pxr = window.devicePixelRatio;
let destH = (destW * h) / w;
mainCanvas.style.width = destW + "px";
mainCanvas.style.height = destH + "px";
destW *= pxr;
destH *= pxr;
mainCanvas.width = destW;
mainCanvas.height = destH;
ctx.imageSmoothingQuality = "medium";
ctx.drawImage(img, 0, 0, destW, destH);
}
<img
id="img"
style="display: none"
src="https://work.otzar.org/example.png"
/>
<button onclick="draw('img')">drawImage from img</button>
<button onclick="draw('cnv')">drawImage from canvas</button>
<br />
<canvas id="cnv"> </canvas>
Upvotes: 1