transforms not taking effect for fillRect and drawImage?
jkozak opened this issue · comments
Expected Behaviour
The code below, run with the commented line enabled and then disabled
should produce two files that differ.
Actual Behaviour
The files produced are identical.
Steps To Reproduce
-
run code below, copy output file to
out1.png
-
comment out commented line, rerun
-
compare
out.png
andout1.png
Any Relevant Code Snippets
"use strict";
const PImage = require("pureimage");
const fs = require('fs');
const img1 = PImage.make(100, 100)
const ctx = img1.getContext('2d');
ctx.scale(0.5,1.0); // !!! comment this out and rerun !!!
ctx.fillStyle = 'red';
ctx.fillRect(0,0,50,50);
PImage.encodePNGToStream(img1, fs.createWriteStream('out.png')).then(() => {
console.log("wrote out the png file to out.png");
}).catch((e)=>{
console.log("there was an error writing");
});
Platform
OS: NixOS 22.11
Node Version: v18.12.1
NPM Version: 8.9.12
PureImage Version: 0.3.14
Any Additional Info
I observe similar problems with context.drawImage
.
Can you confirm this is happening with the current version from master? I just created a test from your code and was able to see the rectangle be resized. Note that the background is transparent, so a 50x50 red rect will look similar to a 100x100 red rect.
Still happening using commit 355ea2b.
The files produced on the two runs are identical:
[nix-shell:/tmp/flatland]$ sha1sum out*
e97ee940bf787779a67b0734ebc43a840fc3c842 out0.png
e97ee940bf787779a67b0734ebc43a840fc3c842 out.png
Worried that I was doing something stupid, I rewrote the test code to write out both cases:
"use strict";
const PImage = require("pureimage");
const fs = require('fs');
function drawRect(doScale,fn) {
const img1 = PImage.make(100, 100)
const ctx = img1.getContext('2d');
if (doScale)
ctx.scale(0.5,1.0);
ctx.fillStyle = 'red';
ctx.fillRect(0,0,50,50);
PImage.encodePNGToStream(img1, fs.createWriteStream(fn)).then(() => {
console.log(`wrote out the png file to ${fn}`);
}).catch(e=>{
console.log(`there was an error writing: ${e}`);
});
}
drawRect(false,"out-f.png");
drawRect(true, "out-t.png");
same results.
Okay. I see now. The fillRect
method directly sets pixels. It doesn't use the transforms. Really it should just create a rect path and fill it, but that breaks other things. Researching.
doing fillRect()
as a path isn't filling the exact same pixels as the plain for loop. I've made a few tweaks to improve it but it still isn't perfect. For now I'm using to use the forLoop path if the current transform is the identity transform. If it's not then it takes the path root. This should fix the bug.
I just released 0.3.16. Can you test that this fixes the transforms for you?
Happy to confirm that this fixes the issue my test code illustrates.