0

I am using WPF objects to generate an bitmap image in memory. The program that does this resides in a WCF web service. The image renders correctly when I run on locally on IISExpress, and on a test IIS 7 server. However, when running on a server used by QA, the image is not rendered correctly. More specifically, only the top 22px lines of a 250px height image are rendered. The settings on both the test server and the QA server are supposed to be identical (insert skeptical face here).

Question: What possible settings in IIS could be effecting this image rendering? Also, I'm thinking there could possibly be a threading issue since RenderTargetBitmap renders asynchronously, and I do get a partial image.

Here is the code I'm using:

private byte[] RenderGauge(ViewData viewData)
{
    double resolution = 4 * ReSize;
    double dpi = 96 * resolution;
    var view = new Gauge();
    var vm = new GuageViewModel(viewData);

    view.Measure(new Size(350, 70));
    view.Arrange(new Rect(new Size(350, 70)));

    var bounds = VisualTreeHelper.GetDescendantBounds(view);
    if (bounds != Rect.Empty)
    {
        height = (int)(Math.Floor(bounds.Height) + 1);
        width = (int)(Math.Floor(bounds.Width) + 1);
        size = new Size(width, height);
    }

    var bitmap = new RenderTargetBitmap((int)(width * resolution), (int)(height * resolution), dpi, dpi, PixelFormats.Pbgra32);
    var visual = new DrawingVisual();
    using (var context = visual.RenderOpen())
    {
        var brush = new VisualBrush(view);
        context.DrawRectangle(brush, null, new Rect(new Point(), bounds.Size));
    }

    bitmap.Render(visual);

    var encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(bitmap));

    byte[] img;
    using (var MS = new MemoryStream())
    {
        encoder.Save(MS);
        img = MS.ToArray();
    }

    img = img == null ? new byte[0] : img;
    return img;
}
Los2000
  • 54
  • 8
  • It may be a threading issue. Is the `viewData` changing while rendering? – Iron Oct 17 '17 at 01:29
  • @Iron; No, viewData is set before the method is called, and no changes are made within the method. – Los2000 Oct 17 '17 at 03:08
  • How about render the `view` directly: `bitmap.Render(view);`? – Iron Oct 17 '17 at 03:31
  • Any methods in other thread are modify the ·viewData· Synchronously? – Iron Oct 17 '17 at 03:36
  • viewData is a POCO used to inject setup data into the method. It is not used in any other thread, and is never modified in the view model constructor. Also, the issue persists when rendering the view directly. – Los2000 Oct 17 '17 at 17:32

1 Answers1

0

So, I'm doing exactly the same thing and I had a number of issues rendering files. I've found that using a binding to a bitmap in the XAML helps. The code from my view model that returns the image source is:

    public Uri ImageUri
    {
        get { return new Uri(ImagePath, UriKind.Absolute); }
    }

    public BitmapImage ImageSource
    {
        get
        {
            try
            {
                if (string.IsNullOrEmpty(ImagePath) || !File.Exists(ImagePath))
                    return null;

                var image = new BitmapImage();
                image.BeginInit();
                image.CacheOption = BitmapCacheOption.OnLoad;
                image.UriSource = ImageUri;
                image.EndInit();

                return image;
            }
            catch (Exception e)
            {
                var logger = LogManager.GetLogger(typeof(ImageDetails));
                ExceptionHelper.LogExceptionMessage(logger, e);
            }

            return null;
        }
    }

Then in the XAML I bind to the ImageSource property.

I think that most problems with RenderTargetBitmap are related to asynchronous bindings in the XAML becauses the render method is synchronous.

David Brunning
  • 575
  • 7
  • 18
  • Thanks for the response David. Unfortunately, I never was able to resolve it, and in order to move forward I had to rewrite the routine using the old System.Drawing library (GAH! Still not happy about it). – Los2000 May 17 '18 at 22:18