What's a good way to Render to a bitmap that is a different size to the Visual?

I've got a fancy looking chart control I've written, and people will use it to generate plots for Powerpoint presentations, so I need to be able to copy the plots to some fixed size like say 1024x768.

Say I have a button "Copy Plot To Bitmap". Ok my code will look like this:

private BitmapSource RenderToBitmap(double width, double height)

{

double baseHeight = this.ActualHeight;

double baseWidth = this.ActualWidth;

this.LayoutTransform = new ScaleTransform(baseWidth/width, baseHeight/height);

RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96d*width/baseWidth, 96d*height/baseHeight, PixelFormats.Default);

rtb.Render(this);

BmpBitmapEncoder encoder = new BmpBitmapEncoder();

encoder.Frames.Add(BitmapFrame.Create(rtb));

FileStream fs = File.Open(@"c:\test.bmp", FileMode.Create);

encoder.Save(fs);

fs.Close();

this.LayoutTransform = new ScaleTransform(1, 1);

return rtb;

}

the problem is, is that the Transform isn't applied until later. So I guess I need to set the tranform, wait until it is rendered, and then copy it to the bitmap. Or is there a better way that someone has come up with



Answer this question

What's a good way to Render to a bitmap that is a different size to the Visual?

  • psycho_billy

    to render just part of an image, try using an ImageBrush and its Viewbox property. the following code sample will render the chunk of the image from 33% to 66% in the horizontal direction and from 25% to 75% in the vertical direction.

    you can also add ViewboxUnits="Absolute" to the ImageBrush and work in terms of pixels instead of percentages.

    <Rectangle
    x:Name="image"
    Margin="0,0,3,0"
    RadiusX="5"
    RadiusY="5"
    HorizontalAlignment="Left"
    VerticalAlignment="Top"
    Width="40"
    Height="40">
    <Rectangle.Fill>
    <ImageBrush
    AlignmentX="Left"
    AlignmentY="Center"
    TileMode="None"
    Stretch="Uniform"
    Viewbox="0.3333,0.25,0.3333,0.50"
    ImageSource="myimage.jpg"/>
    </Rectangle.Fill>
    </Rectangle>

  • ispjka

    Bigger or smaller, and with a different aspect ratio. But I have it all worked out now. I wanted to change the size of the image, but retain the font size of any text I wanted rendered. I just wasn't aware of the UpdateTranform () method. There's a lot of stuff to discover in this new WPF stuff.


  • Dinus

    I'm not familiar with image "box", but you could set the RenderTransform to a TranslateTransform(x,y) that is set up for the piece you want, and if it is a Canvas of 600x400 set ClipToBounds to true and then render the image to it.
  • Jono378

    Got the solution!

    After I set the LayoutTransform I need to call

    this.UpdateLayout();

    Adding that enables you to make the above code render any visual to any size bitmap and save it to disk.


  • fpsoft

    I know you figured it out, but I'm trying to do a kind of similar thing. I want to inject an image(1280*1024) into an image"box" of 600*400. But I don't want to resize it, I want to take a piece out of the image.

  • Eric Donoho

    Hi John,

    Am I getting this right You're tryin to fit a bigger image into a smaller image"box"

  • What's a good way to Render to a bitmap that is a different size to the Visual?