Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: WPF VB.NET
ok, it's a simple case, i rendered a viewport3d object using RenderTargetBitmap @ resolution 600 * 600 @ 96 dpi, the problem is there are a big deference in quality between the view port and the saved image:
 
here are some code:
 
'rendering viewport3D to image
Dim viewportPlate As New RenderTargetBitmap(600, 600, 96 , 96 , PixelFormats.Pbgra32)
viewportPlate.Render(viewport3d)
 
'path to save
Dim path As String = imgSave
Dim fs As FileStream = New FileStream(path, FileMode.Create)
 
'encoding to PNG and saving
Dim encoder As BitmapEncoder = New PngBitmapEncoder()
encoder.Frames.Add(BitmapFrame.Create(viewportPlate))
encoder.Save(fs)
 

 
now i tried to render to a larger resolution then scale it down and it got better, but a new problem arises of the big render time (because of the software rendering) and the out of memory issues!!!
 
i'm using .net 4.0, is there a clear way to achieve a better anti-aliased solutions and render times, as it was for GDI+ which i consider is a bless besides WPF?????
 
any tips will be welcome Smile | :)
Posted 20-Jun-11 3:10am
bat3a592
Comments
SAKryukov at 20-Jun-11 9:48am
   
Which one is poor quality?
--SA
bat3a at 21-Jun-11 0:02am
   
the saved one, her is a test, i captured the viewport3d using print screen
http://imageshack.us/photo/my-images/200/unledfy.jpg

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

First of all, I must apologise because the extension method I'm going to show you is C#, but it shouldn't be too hard for you to convert it into VB.
public static RenderTargetBitmap RenderBitmap(this Visual visualToRender)
{
  double scale = 600 / 96;
  RenderTargetBitmap bmp = new RenderTargetBitmap
  (
    (int)(scale * (visualToRender.ActualWidth + 1)),
    (int)(scale * (visualToRender.ActualHeight + 1)),
    scale * 96,
    scale * 96,
    PixelFormats.Default
  );
  bmp.Render(visualToRender);
  return bmp;
}
[Edit]The OP cannot use this code sample because he needs to scale the image again, and the process is slow.
 
The issue you have here is that RenderTargetBitmap does not use hardware rendering. It is entirely software rendered, hence the reason that it is prohibitively slow to render (this also counts to explain why the quality is reduced). If you could bear to introduce an external resource into your application, you could use SlimDX (a free DirectX wrapper) to render the viewport from your application.
  Permalink  
v2
Comments
bat3a at 22-Jun-11 9:57am
   
thanks man i tried this solution and it works but i can't use this as the resulted image needs to be re-sized again-and when i do that it simply reverts back to the low quality-, another thing is the huge computing time, which renders this solution as not applicable, any more thoughts??
bat3a at 22-Jun-11 10:08am
   
so i just include the binaries and use some functions?, do you know how to find rendertargetbitmap equivalent function in slimDX, or have a tut about that, thanks.
Pete O'Hanlon at 22-Jun-11 10:32am
   
Off the top of my head, I don't know what you'd need to call in SlimDX. I do know that you can do this in C++ using:
 
extern IDirect3DDevice9* g_pd3dDevice;
 
void CaptureDevice(uint width, uint height)
{
IDirect3DSurface9* pSurface;
g_pd3dDevice->CreateOffscreenPlainSurface(
width, height,
D3DFMT_A8R8G8B8,
D3DPOOL_SCRATCH,
&pSurface,
NULL);
g_pd3dDevice->GetFrontBufferData(0, pSurface);
D3DXSaveSurfaceToFile("c:\\File.jpg",D3DXIFF_JPG,pSurface,NULL,NULL);
pSurface->Release();
}
 
So, the C# equivalent would need to use some combination of this. (Note that you have to get the Direct3D context to do this).
bat3a at 22-Jun-11 10:57am
   
is this using the slimDX, or directly from directX???
Pete O'Hanlon at 22-Jun-11 11:10am
   
That's a version of the C++ DirectX code that would have to be translated. The SlimDX version would be vastly simpler.
bat3a at 22-Jun-11 12:03pm
   
trying to convert this code to vb.net, here is what i got:
 
extern IDirect3DDevice9* g_pd3dDevice
Private Sub CaptureDevice(ByVal width As uint, ByVal height As uint)
Dim pSurface As IDirect3DSurface9
g_pd3dDevice.CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, pSurface, Nothing)
g_pd3dDevice.GetFrontBufferData(0, pSurface)
D3DXSaveSurfaceToFile("c:\File.jpg", D3DXIFF_JPG, pSurface, Nothing, Nothing)
pSurface.Release()
End Sub
 
is there any libs i should include in the code???
thanks for helping
Pete O'Hanlon at 22-Jun-11 12:32pm
   
You'll need D3D9.dll to get this to run.
bat3a at 22-Jun-11 13:43pm
   
after an hour with playing with code i accomplished nothing, i'm downloading slimDX SDK and will see how things goes
bat3a at 22-Jun-11 15:18pm
   
ok i starting new thread for rendering viewport3d or any visual using slimDX, i report here if i find a solution.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Schatak 394
1 OriginalGriff 300
2 Abhijit Ghosh (Subho) 125
3 _Amy 115
4 Andreas Gieriet 110
0 OriginalGriff 7,107
1 Sergey Alexandrovich Kryukov 5,623
2 Maciej Los 3,504
3 Peter Leow 3,373
4 DamithSL 2,505


Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 22 Jun 2011
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100