Add image through assembly (custom code)

Posted by: ricardo.pereira on 19 October 2020, 3:12 am EST

  • Posted 19 October 2020, 3:12 am EST

    Hi,

    We would like to know if it's possible to bind an image that comes from an assembly to one of our reports.

    We have a report that for each page calls an API endpoint to retrieve a dynamic image potentially 31 times (one for each day of the calendar). This methodology is proving to be really slow specially when we have reports with 50+ pages (31*50 = 1550 calls).

    For this reason we started using custom code on said report (by adding a reference to a DLL) and we have an Image control that seems to be fetching the image through the DLL with no issues but it isn't binding it on the report properly (we get a blank image only). We know the DLL reference is working properly because we tested it on other TextBox Elements.

    I've tried using the following methods:

    public static Image GetHoursImage(string hours, string ncs)
    public static FileStream GetHoursImage(string hours, string ncs)
    public static byte[] GetHoursImage(string hours, string ncs)

    If I use
    File.WriteAllBytes("test.jpeg", testImg);
    the image is downloaded to my local machine and I can see it's producing the correct result.

    I've also done some speed tests matching the web service implementation vs the assembly implementation and for a report with 52 pages I got the following timings when exporting to pdf:
    - Web Service -> 41s
    - Assembly -> 8s

    This is the code for both implementations:


    <Image Name="HoursImage">
    <DataElementName>HoursImage</DataElementName>
    <Height>0.32cm</Height>
    <Left>2.04895cm</Left>
    <MIMEType>image/bmp</MIMEType>
    <Sizing>Fit</Sizing>
    <Source>External</Source>
    <Value>=Fields!BaseUrl.Value & "/api/ReportImage/" & Fields!Hours.Value</Value>
    <Width>11.4992cm</Width>
    <ZIndex>232</ZIndex>
    </Image>
    <Image Name="HoursImage">
    <DataElementName>HoursImage</DataElementName>
    <Height>0.32cm</Height>
    <Left>2.04895cm</Left>
    <MIMEType>image/bmp</MIMEType>
    <Sizing>Fit</Sizing>
    <Source>External</Source>
    <Value>=Reports.CalcFunctions.CalculationFunctions.GetHoursImage(Fields!Hours.Value, Fields!NCs.Value)</Value>
    <Width>11.4992cm</Width>
    <ZIndex>232</ZIndex>
    </Image>


    Can you see any obvious mistake I might be doing?

    Best Regards,
    Ricardo Pereira
  • Replied 19 October 2020, 3:24 pm EST

    Hello,

    In my understanding, the main problem is in the "public static byte[] GetHoursImage(string hours, string ncs)" method as it does not return the compatible Image with ImageControl that's why it show blank image. Could you please share the code of the method so that I can try at my end and anything else which can help me to replicate the same scenario at my end.

    Thanks,
    Mohit
  • Replied 19 October 2020, 7:33 pm EST

    Hi Mohit,

    Thank you for your quick reply.

    The code present on the assembly is the following:

    public static Image GetHoursImage(string hours, string ncs) {
    var testImg = CreateImage(hours, ncs);

    // This works well - OK
    File.WriteAllBytes("test.jpeg", testImg);

    // Returning Image - NOK
    using (var ms = new MemoryStream(testImg)) {
    return Image.FromStream(ms);
    }

    // // Returning FileStream - NOK
    // using (var ms = new MemoryStream(testImg)) {
    // using (var fs = new FileStream("savePath", FileMode.Create)) {
    // ms.WriteTo(fs);

    // return fs;
    // }
    // }

    // // Returning byte[] - NOK
    // return testImg;
    }

    private static byte[] CreateImage(string hours, string ncs) {
    var bmp = new Bitmap(480, 10);

    using (var graphics = Graphics.FromImage(bmp)) {
    var brush = new SolidBrush(Color.DarkGray);

    graphics.FillRectangle(brush, new Rectangle(0, 0, 480, 10));
    }

    var ms = new MemoryStream();
    bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);

    return ms.ToArray();
    }


    The code on the report designer was pasted yesterday but here it is again:

    <Image Name="HoursImage">
    <DataElementName>HoursImage</DataElementName>
    <Height>0.32cm</Height>
    <Left>2.04895cm</Left>
    <MIMEType>image/jpeg</MIMEType>
    <Sizing>Fit</Sizing>
    <Source>External</Source>
    <Value>=Reports.CalcFunctions.CalculationFunctions.GetHoursImage(Fields!Hours.Value, Fields!NCs.Value)</Value>
    <Width>11.4992cm</Width>
    <ZIndex>232</ZIndex>
    </Image>


    Tell me if you need something else.

    Best regards,
    Ricardo Pereira
  • Replied 20 October 2020, 3:45 am EST

    Hello Ricardo,

    Could you please try after returning the Byte array in the "GetHoursImage" instead of Image and change the source of Image to External to Database.

    Hope it helps.

    Thanks,
    Mohit
  • Replied 20 October 2020, 3:55 am EST

    Hi Mohit,

    Just tried that approach but unfortunately the problem persists.

    Did you manage to get it working? If so can you please provide some code?

    Thanks in advance.

    Best regards,
    Ricardo Pereira
  • Marked as Answer

    Replied 20 October 2020, 4:28 am EST

    Hello,

    Please refer to the attached class library and report to demonstrate the same.

    Thanks,
    MohitTestImage.zip
    testReport.zip
  • Replied 20 October 2020, 9:36 pm EST

    Hi Mohit,

    Thank you very much for your reply, that configuration worked perfectly!!

    Best Regards,
    Ricardo Pereira
Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels