imazen/imageflow-dotnet

Error when resizing one image to multiple sizes

bjornsallarp opened this issue · 1 comments

I'm testing this library and my use case is that I have one image that I want to output to multiple sizes and jpg quality. I figured it would probably be best to decode the image once and that the Branch-method would allow me to do this? Here's my test code:

`public async Task Get([FromQuery]uint width = 1000)
{
var encoder = new LibJpegTurboEncoder {Progressive = true, Quality = 90};

        using (var b = new FluentBuildJob())
        {
            var bytes = await System.IO.File.ReadAllBytesAsync(@"C:\\Users\\bjorn.sallarp\\Pictures\\arkaden-takterrass.jpg");
            await b.Decode(new ArraySegment<byte>(bytes))
                .Branch(x => HighRes(x, width))
                .Branch(x => LowRes(x, width))
                .EncodeToStream(Response.Body, false, encoder)
                .FinishAsync();
        }
    }

    private BuildEndpoint HighRes(BuildNode arg, uint width)
    {
        var outfile = $@"C:\\Users\\bjorn.sallarp\\Pictures\\arkaden-takterrass-hires.jpg";
        var encoder = new LibJpegTurboEncoder { Progressive = true, Quality = 90 };
        return arg.ConstrainWithin(width, null, null,
                downFilter: InterpolationFilter.Lanczos,
                upFilter: InterpolationFilter.Mitchell,
                interpolationColorspace: ScalingFloatspace.Linear,
                resampleWhen: ResampleWhen.Always)
            .Encode(new StreamDestination(System.IO.File.OpenWrite(outfile), true), encoder);
    }

    private BuildEndpoint LowRes(BuildNode arg, uint width)
    {
        var outfile = @"C:\\Users\\bjorn.sallarp\\Pictures\\arkaden-takterrass-lowres.jpg";
        var encoder = new LibJpegTurboEncoder { Progressive = true, Quality = 60 };
        return arg.ConstrainWithin(width, null)
            .Encode(new StreamDestination(System.IO.File.OpenWrite(outfile), true), encoder);
    }

This is the error I get:ImageflowException: GraphInvalid: InvalidNodeConnections: Node type primitive_encoder prohibits child nodes, but had 1 outbound edges. atimageflow_core\src\flow\execution_engine.rs:77:21https://github.com/imazen/imageflow/blob/6f7f054d868c9726a42eaaae7277900a5cb4e3a1/imageflow_core\src\flow\execution_engine.rs#L77imageflow_core\src\context.rs:244:59https://github.com/imazen/imageflow/blob/6f7f054d868c9726a42eaaae7277900a5cb4e3a1/imageflow_core\src\context.rs#L244imageflow_core\src\context_methods.rs:32:68https://github.com/imazen/imageflow/blob/6f7f054d868c9726a42eaaae7277900a5cb4e3a1/imageflow_core\src\context_methods.rs#L32Active node:NodeDebugInfo { stable_id: -1, params: Json( Encode { io_id: 2, preset: LibjpegTurbo { quality: Some( 60 ), progressive: Some( true ), optimize_huffman_coding: None } } ), index: NodeIndex(1)}989`

By accident i found that this works:
b.Decode(new ArraySegment<byte>(bytes)); await b.Decode(new ArraySegment<byte>(bytes)) .Branch(x => HighRes(x, width-1)) .Branch(x => HighRes(x, width-2)) .Branch(x => HighRes(x, width-3)) .Branch(x => HighRes(x, width-4)) .Branch(x => LowRes(x, width)) .EncodeToStream(Response.Body, false, encoder) .FinishAsync();

I guess it has something to do with how the command is built? Perhaps it would have worked if FinishAsync could be called directly from Branch, without adding the last output outside of the branch with EncodeToStream?

Thank you for reporting this! It has been fixed in 8aa89b2 (will be released as v0.4.2).