CaptureToBitmap() with transparency

After some experimentation, I finally give up.
I tried every way I could find/come up with, to make the Viewport background transparent. The result of CaptureToBitmap() will always be a 24bpp bitmap without alpha.

Since ViewCaptureToFile is able to save transparent PNGs, is there any way to do so via RhinoCommon?

Hi,

After you capture did you try this?

var bitmap = doc.Views.ActiveView.CaptureToBitmap(true, true, true);
bitmap.MakeTransparent();

I looked into it, but it’s no use.

MakeTransparent() works like the magic wand tool in PS with zero tolerance, which is a pretty bad way to make an image transparent. This does neither account for aliasing nor for the occasional shading color that could get the same color as the background color.

I don’t see a way of doing this from RhinoCommon. I’ll add the wish to the pile…

thank you very much!

Hi @dale
Just curious if this was implemented in RhinoCommon yet?

Yes it has. In the Rhino WIP, use Rhino.Display.ViewCapture.

– Dale

Oh that’s great, thank you

Hi @dale,
I have a problem to use that correctly, I would be glad if you or somebody else could help me. This is my code:

//fp = filepath
//vpN = viewport name
void rCommonCap(string fp, string vpN, double scaleFac){
Rhino.Display.RhinoView view;
if(String.IsNullOrEmpty(vpN)){
view = RhinoDocument.Views.ActiveView;
} else {
view = RhinoDocument.Views.Find(vpN, false);
}
Rhino.Display.RhinoViewport vp = view.ActiveViewport;
Size size = new Size((int) (vp.Size.Width * scaleFac), (int) (vp.Size.Height * scaleFac));
//Bitmap capture = view.CaptureToBitmap(size);
Bitmap capture2 = Rhino.Display.ViewCapture.CaptureToBitmap(view);
if(System.IO.File.Exists(fp)){
System.IO.File.Delete(fp);
}
capture2.Save(fp);
}

However, it doesnt work. I get an CS0120 error, telling me, that an object reference is necessary. But as far as I understand, the Rhino.Display.ViewCapture.CaptureToBitmap wants a Rhino.Display.RhinoView. Where is my mistake? My programming skills make me feel nooby as hell…

To be honest, I didn’t write the code myself and had a hard time to understand what is happening there. Want I want to achive is a series of PNGs with a transparent background to make a video from.
If the view.CaptureToBitmap(size) line is used, everything works fine, just with the background being opaque.

Hi @henry.langner,

Here is a simple example:

SampleCsViewCapture.cs

Does this help?

– Dale

4 Likes

Yes it did, thank you very much! Love, peace and cotton candy for you!

Hi @dale ,
In the past I was using: RhinoDoc.ActiveDoc.Views.ActiveView.CaptureToBitmap(…) to generate hundreds of images at a time. However, it was quite slow and was thinking if there was a way to speed it up. I tried your solution using the ViewCapture class but it seems like it takes about the same time for each frame. Is there a faster way? I was reading here: http://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Display_DisplayBitmap.htm
that you can potential use the Bitmap used by the display. Any ideas of how to do it?

I hope it is alright I am posting it here. Thanks!
Stam

Hi @psarras_st,

I don’t know any way of speeding up view capturing. Perhaps more information on what you are doing and why might help us understand what you need?

– Dale

Hi @dale

I basically have saved a few camera positions in GH and I want to batch save all their views to a file.
What I am doing up untill know is move the viewport camera, and using RhinoDoc.ActiveDoc.Views.ActiveView.CaptureToBitmap(…) . I think this can be done faster, because Rhino’s viewport is doing it! When I am moving the camera using the mouse at around 20-30 fps per second, while when I use the previous command I might be getting 2fps.

I also stumbled on my search of Rhino Common to this class: DisplayBitmap Class, that states on its description:

“A bitmap resource that can be used by the display pipeline (currently only in OpenGL display). Reuse DisplayBitmaps for drawing if possible; it is much more expensive to construct new DisplayBitmaps than it is to reuse existing DisplayBitmaps.”

I thought it might have been the way to go, but I am not sure how to call it. Let me know if you need more information.

best,
Stam

Hi @psarras_st,

The DisplayBitmap class is used for drawing bitmaps in a display conduit. It doesn’t have any to do with capturing a view.

– Dale

Rhino’s viewport is not transferring data from the GPU to local memory in order to create a bitmap. That is an expensive operation which is why it takes longer to generate bitmaps than to just draw in the viewport.

@stevebaer @dale Is there a way to optimise that then? Threading it maybe?

Thank you for your help

hi @Dale,

I am trying to follow your sample:

in Python.
When trying to set the Width, I get this error:
Message: static property 'Width' of 'ViewCapture' can only be assigned to through a type, not an instance

here is the code snippet:

    import Rhino.Display 
    import scriptcontext
    import System

    view = scriptcontext.doc.Views.ActiveView

    view_capture = Rhino.Display.ViewCapture
    view_capture.Width = 1000

    bitmap = view.CaptureToBitmap()

How can I define the capture properties? I am trying to capture current view with bitmap with custom view size and not to show any of the view widgets like title and world axes…

thanks,

–jarek

Nevermind! I found your other good sample here, it works now: