imazen / imageflow-dotnet

The official .NET API for Imageflow, the Rust image processing and optimization engine for web servers
GNU Affero General Public License v3.0
143 stars 25 forks source link

CreateCanvas color serialization error #29

Closed jakenuts closed 3 years ago

jakenuts commented 3 years ago

Sorry to keep pushing these edge use cases, but I ran into a problem using CreateCanvasBgr32/CreateCanvasBgra32 and it appears that the AnyColor bit is not serializing correctly.

using (var job = new ImageJob())
{
   await job.CreateCanvasBgr32(100, 100, AnyColor.Black)
      .EncodeToStream( new MemoryStream(), true, new MozJpegEncoder(100))
      .Finish()
      .InProcessAsync();
}

Results in an Imageflow.Bindings.ImageflowException I'm guessing because of this {>} bit of the json:

{"create_canvas":{"w":100,"h":100,"color":{>},"format":"bgr_32"}}

Thanks!

lilith commented 3 years ago

Thank you so much for the PR! I've released https://github.com/imazen/imageflow-dotnet/releases/tag/v0.7.23 with your changes.

jakenuts commented 3 years ago

I'm having some difficulty figuring out the right watermark settings to overlay one image on another without any scaling but with some precise positioning. Is it possible to load an image, then load others and use DrawImageExactTo to overlay them on the original? I had success with one, but can't do it twice without an error. This is what I'm doing..


// canvasSrc loaded from a file
var canvas = job.Decode(canvasSrc);

foreach(var layer in overlays){

   // layerImg loaded from file, finalRect calced from layer size & position
   await job.Decode(layerImg).DrawImageExactTo(
                            canvas,
                            finalRect,
                            new ResampleHints(),
                            CompositingMode.Compose)
                        .EncodeToStream(outContent.Stream, false, encoder)
                        .Finish()
                        .InProcessAsync();
}

// not doing anything with canvas?
lilith commented 3 years ago

You're await and calling .Finish multiple times. Just do it once.

On Sat, Mar 20, 2021, 9:55 PM James White @.***> wrote:

I'm having some difficulty figuring out the right watermark settings to overlay one image on another without any scaling but with some precise positioning. Is it possible to load an image, then load others and use DrawImageExactTo to overlay them on the original? I had success with one, but can't do it twice without an error. This is what I'm doing..

// canvasSrc loaded from a file var canvas = job.Decode(canvasSrc);

foreach(var layer in overlays){

// layerImg loaded from file, finalRect calced from layer size & position await job.Decode(layerImg).DrawImageExactTo( canvas, finalRect, new ResampleHints(), CompositingMode.Compose) .EncodeToStream(outContent.Stream, false, encoder) .Finish() .InProcessAsync(); }

// not doing anything with canvas?

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/imazen/imageflow-dotnet/issues/29#issuecomment-803507817, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2LH7W22OIY44XT2NIHI3TEVU2PANCNFSM4ZNUWVKA .

jakenuts commented 3 years ago

That makes sense, should I be calling encode/finish on the canvas node or the last buildnode from DrawImageExactTo? I think the latter works but only if there is only one layer.

jakenuts commented 3 years ago

Aha! Kept treating the canvas as an independent part rather than layering up the overlays.


            var lastNode = job.CreateCanvasBgr32(500, 500, AnyColor.Black);

            foreach (var overlay in Overlays)
            {
                lastNode = job.Decode(overlay).DrawImageExactTo(
                    lastNode, drawRect, hints, CompositingMode.Compose
                );

                drawRect.Offset(100,100);
            }

            await lastNode.EncodeToStream(file, false, new LodePngEncoder())
                .Finish()
                .InProcessAsync();