wpfwcfiis-7rendertargetbitmap

Creating bitmap in memory using RenderTargetBitmap fails in production WCF Service


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;
}

Solution

  • 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.