weixin_39518840
2020-12-02 12:54 阅读 2

context.drawImage

Hi, any ideas why .addImage wouldn't work on a context?


PImage.decodeJPEGFromStream(fs.createReadStream(filePath)).then((img) => {
  var ctx = img.getContext('2d');
  ctx.fillStyle = "red";
  ctx.fillRect(0, 0, img.width, img.height);

  var maskCanvas = PImage.make(img.width, img.height);
  var maskCtx = maskCanvas.getContext('2d');

  maskCtx.fillStyle = "black";
  maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height);
  ctx.drawImage(maskCanvas, 0,0);


  PImage.encodeJPEGToStream(img, fs.createWriteStream(saveOut)).then(()=> {
    console.log("wrote out the png file to out.png");
  }).catch((e)=>{
    console.log("there was an error writing");
  });
});

Here is a sample where the image should come up black but the drawImage call doesn't seem to be effective. This should work with any image load, basically just trying to get a working test case before moving on.

该提问来源于开源项目:joshmarinacci/node-pureimage

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

12条回答 默认 最新

  • weixin_39655362 weixin_39655362 2020-12-02 12:54

    I've had issues with this in the last and came down to there being something not quite right with the PNG I was trying to load and pngjs wasn't handling it terribly well. Can you try opening the PNG your working with in Photoshop and re-saving it? Falling that could you try running your code against my fork? I'd do it but I'm actually in bed right now 😋

    点赞 评论 复制链接分享
  • weixin_39518840 weixin_39518840 2020-12-02 12:54

    Heya, I gave a shot to the fork and it didn’t work either. I simplified the example to just have a simple canvas (no image) and draw a second layer over the top.. to illustrate:

    var bottomCanvas = PImage.make(100,100); var ctx = normCanvas.getContext('2d'); ctx.fillStyle = "red"; ctx.fillRect(0, 0, normCanvas.width, normCanvas.height);

    var maskCanvas = PImage.make(normCanvas.width, normCanvas.height); var maskCtx = maskCanvas.getContext('2d');

    maskCtx.fillStyle = "black"; maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height); ctx.drawImage(maskCanvas, 0,0); PImage.encodeJPEGToStream(normCanvas, fs.createWriteStream("./Save2.jpeg")). then(()=> { console.log("wrote out the png file to out.png"); }).catch((e)=>{ console.log("there was an error writing"); });

    Any ideas?

    Thanks,

    JJ

    On January 8, 2018 at 10:40:31 PM, Robert Main (notifications.com) wrote:

    I've had issues with this in the last and came down to there being something not quite right with the PNG I was trying to load and pngjs wasn't handling it terribly well. Can you try opening the PNG your working with in Photoshop and re-saving it? Falling that could you try running your code against my fork https://github.com/robertmain/node-pureimage/tree/fix-unit-tests? I'd do it but I'm actually in bed right now 😋

    — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/joshmarinacci/node-pureimage/issues/46#issuecomment-356194267, or mute the thread https://github.com/notifications/unsubscribe-auth/AEorqLn4KKZcGCqf2nFd2QkKcGD_chWxks5tIwnfgaJpZM4RXXNB .

    点赞 评论 复制链接分享
  • weixin_39518840 weixin_39518840 2020-12-02 12:54

    Figured it out…

    I think it has to do with a canvas being able to detect certain things about an image when it is the dom. Basically, the draw image method has a couple overloads that take more args.

    https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage

    This overload works: void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

    When debugging into this overload:

    void ctx.drawImage(image, dx, dy);

    The code looks for the dWidth param in a foreach loop and, if that arg doesn’t have a value, the foreach loop just quits out and doesn’t do any writing.

    Here is the code from context.js in the canvas lib

    drawImage(bitmap, sx,sy,sw,sh, dx, dy, dw, dh) {

    // this is JJ’s comment — not in actual code — the var here, if not received in the method args, causes the // method to quit out w/out writing to setPixelRGBA for(var i=0; i<dw; i++) { var tx = i/dw; var ssx = Math.floor(tx*sw)+sx; for(var j=0; j<dh; j++) { var ty = j/dh; var ssy = sy+Math.floor(ty * sh); var rgba = bitmap.getPixelRGBA(ssx,ssy); this.bitmap.setPixelRGBA(dx+i, dy+j, rgba); } } }

    Anyway, I love the project and wish you luck with it!

    Thanks,

    Jason Janofsky

    On January 9, 2018 at 9:03:33 AM, Jason Janofsky (jasonjanofsky.com) wrote:

    Heya, I gave a shot to the fork and it didn’t work either. I simplified the example to just have a simple canvas (no image) and draw a second layer over the top.. to illustrate:

    var bottomCanvas = PImage.make(100,100); var ctx = normCanvas.getContext('2d'); ctx.fillStyle = "red"; ctx.fillRect(0, 0, normCanvas.width, normCanvas.height);

    var maskCanvas = PImage.make(normCanvas.width, normCanvas.height); var maskCtx = maskCanvas.getContext('2d');

    maskCtx.fillStyle = "black"; maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height); ctx.drawImage(maskCanvas, 0,0); PImage.encodeJPEGToStream(normCanvas, fs.createWriteStream("./Save2.jpeg")). then(()=> { console.log("wrote out the png file to out.png"); }).catch((e)=>{ console.log("there was an error writing"); });

    Any ideas?

    Thanks,

    JJ

    On January 8, 2018 at 10:40:31 PM, Robert Main (notifications.com) wrote:

    I've had issues with this in the last and came down to there being something not quite right with the PNG I was trying to load and pngjs wasn't handling it terribly well. Can you try opening the PNG your working with in Photoshop and re-saving it? Falling that could you try running your code against my fork https://github.com/robertmain/node-pureimage/tree/fix-unit-tests? I'd do it but I'm actually in bed right now 😋

    — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/joshmarinacci/node-pureimage/issues/46#issuecomment-356194267, or mute the thread https://github.com/notifications/unsubscribe-auth/AEorqLn4KKZcGCqf2nFd2QkKcGD_chWxks5tIwnfgaJpZM4RXXNB .

    点赞 评论 复制链接分享
  • weixin_39518840 weixin_39518840 2020-12-02 12:54

    Well, I made it to the very last point in my integration and then hit the SRC_OVER globalCompositeOperation limitation. We, unfortunately, are looking for xor. I am going to consider other/implementations to get our project working but.. I wouldn’t mind working the code in, for xor, on the context.js file from pureImage. You have any thoughts on how to approach the operation or code sample from where you guys are pulling from or did you guys just build it yourselves?

    Thanks, in advance for your time!

    Jason Janofsky

    On January 9, 2018 at 1:51:36 PM, Jason Janofsky (jasonjanofsky.com) wrote:

    Figured it out…

    I think it has to do with a canvas being able to detect certain things about an image when it is the dom. Basically, the draw image method has a couple overloads that take more args.

    https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage

    This overload works: void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

    When debugging into this overload:

    void ctx.drawImage(image, dx, dy);

    The code looks for the dWidth param in a foreach loop and, if that arg doesn’t have a value, the foreach loop just quits out and doesn’t do any writing.

    Here is the code from context.js in the canvas lib

    drawImage(bitmap, sx,sy,sw,sh, dx, dy, dw, dh) {

    // this is JJ’s comment — not in actual code — the var here, if not received in the method args, causes the // method to quit out w/out writing to setPixelRGBA for(var i=0; i<dw; i++) { var tx = i/dw; var ssx = Math.floor(tx*sw)+sx; for(var j=0; j<dh; j++) { var ty = j/dh; var ssy = sy+Math.floor(ty * sh); var rgba = bitmap.getPixelRGBA(ssx,ssy); this.bitmap.setPixelRGBA(dx+i, dy+j, rgba); } } }

    Anyway, I love the project and wish you luck with it!

    Thanks,

    Jason Janofsky

    On January 9, 2018 at 9:03:33 AM, Jason Janofsky (jasonjanofsky.com) wrote:

    Heya, I gave a shot to the fork and it didn’t work either. I simplified the example to just have a simple canvas (no image) and draw a second layer over the top.. to illustrate:

    var bottomCanvas = PImage.make(100,100); var ctx = normCanvas.getContext('2d'); ctx.fillStyle = "red"; ctx.fillRect(0, 0, normCanvas.width, normCanvas.height);

    var maskCanvas = PImage.make(normCanvas.width, normCanvas.height); var maskCtx = maskCanvas.getContext('2d');

    maskCtx.fillStyle = "black"; maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height); ctx.drawImage(maskCanvas, 0,0); PImage.encodeJPEGToStream(normCanvas, fs.createWriteStream("./Save2.jpeg")). then(()=> { console.log("wrote out the png file to out.png"); }).catch((e)=>{ console.log("there was an error writing"); });

    Any ideas?

    Thanks,

    JJ

    On January 8, 2018 at 10:40:31 PM, Robert Main (notifications.com) wrote:

    I've had issues with this in the last and came down to there being something not quite right with the PNG I was trying to load and pngjs wasn't handling it terribly well. Can you try opening the PNG your working with in Photoshop and re-saving it? Falling that could you try running your code against my fork https://github.com/robertmain/node-pureimage/tree/fix-unit-tests? I'd do it but I'm actually in bed right now 😋

    — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/joshmarinacci/node-pureimage/issues/46#issuecomment-356194267, or mute the thread https://github.com/notifications/unsubscribe-auth/AEorqLn4KKZcGCqf2nFd2QkKcGD_chWxks5tIwnfgaJpZM4RXXNB .

    点赞 评论 复制链接分享
  • weixin_39655362 weixin_39655362 2020-12-02 12:54

    Hi Jason

    It's actually not my library, I just came across it and pitched in. The library itself is based around the idea that it should mimic the HTML5 canvas API. Additionally - there's some API documentation available here: http://joshmarinacci.github.io/node-pureimage.

    As for how to contribute, I'm writing up some unit tests for existing functionality at the moment(rewriting the test suite to be more along the lines of BDD).

    点赞 评论 复制链接分享
  • weixin_39632982 weixin_39632982 2020-12-02 12:54

    All of the implementation is from scratch. The many composite ops aren't implemented yet. However, are you sure you need XOR? That is very rare in modern day graphics systems. What are you trying to accomplish?

    点赞 评论 复制链接分享
  • weixin_39518840 weixin_39518840 2020-12-02 12:54

    You know, I actually didn’t need xor, I ended up needing destination-atop. I was able to get the implementation working with canvas. I imagine I could get it working much better with PureImage — or at least cleaner without binaries flying all over the place. I have very limited experience with imaging/graphics fundamentals though. Mostly just a consumer of the library with that stuff.

    Thanks,

    Jason J

    On January 11, 2018 at 8:40:53 AM, Josh Marinacci (notifications.com) wrote:

    All of the implementation is from scratch. The many composite ops aren't implemented yet. However, are you sure you need XOR? That is very rare in modern day graphics systems. What are you trying to accomplish?

    — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/joshmarinacci/node-pureimage/issues/46#issuecomment-356986108, or mute the thread https://github.com/notifications/unsubscribe-auth/AEorqHrQO99sGjiTwlM5y7hFesFHvimzks5tJjmVgaJpZM4RXXNB .

    点赞 评论 复制链接分享
  • weixin_39632982 weixin_39632982 2020-12-02 12:54

    I just implemented a fix with unit tests. All forms of drawImage should work now.

    点赞 评论 复制链接分享
  • weixin_39675038 weixin_39675038 2020-12-02 12:54

    I'm having an issue with this. Not quite sure what's up, but my function doesn't seem to have any effect and doesn't throw any errors to help :/.

    Here's the code: `function outline_tiles(ctx) { var x = 0 var y = 0

    PImage.decodePNGFromStream(fs.createReadStream('outline.png')).then((otl) => {
        console.log("outline size is",otl.width,otl.height);
    
        for (z = 0; z < map.length; z++) {
            x = map[z][0] * tile_size
            y = map[z][1] * tile_size
    
            console.log("Outlining pos: [" + x + ", " + y + "]")
    
            ctx.drawImage(otl,
                0, 0, otl.width, otl.height, // source dimensions
                x, y, tile_size, tile_size   // destination dimensions
            );
        }
    });
    

    }`

    I have another function draw squares across a small image to make tiles. That image is then passed on to the function via "ctx". "tile_size" and "map" are globals.

    The console prints "outline size is 32 32" and then cuts to "wrote out png file..." as if it skipped my for loop entirely.

    点赞 评论 复制链接分享
  • weixin_39675038 weixin_39675038 2020-12-02 12:54

    Solved. The drawImage calls apparently didn't have enough time to post to the context before being encoded to the png file. All I had to do was wait .5 seconds via setTimeout() before encoding the file.

    点赞 评论 复制链接分享
  • weixin_39632982 weixin_39632982 2020-12-02 12:54

    Hmm. That's weird. drawImage should be synchronous. Are the images you are drawing (otl?) already fully loaded?

    点赞 评论 复制链接分享
  • weixin_39675038 weixin_39675038 2020-12-02 12:54

    No, it turned out that I needed to wait half a second before encoding the image. Yes, otl -> outline.png. That solved the problem but then revealed another issue ;). I was able to get around it, but I opened an issue for the functionality.

    点赞 评论 复制链接分享

相关推荐