How to set the jpg quality when saving a bitmap in Python or Rhino script

I am able to save a bitmap as a jpg using the script from SampleViewCaptureToFile.py. I’d like to be able to set the jpg quality. I tried the following, but that doesn’t work and I can’t get very far figuring out why.

import System
import Rhino
import scriptcontext as sc
import sys

view = sc.doc.Views.ActiveView
if view:
    view_capture = Rhino.Display.ViewCapture()
    view_capture.Width = view.ActiveViewport.Size.Width
    view_capture.Height = view.ActiveViewport.Size.Height
    view_capture.ScaleScreenItems = False
    view_capture.DrawAxes = False
    view_capture.DrawGrid = False
    view_capture.DrawGridAxes = False
    view_capture.TransparentBackground = False
    bitmap = view_capture.CaptureToBitmap(view)
    if bitmap:
        jpg_encoder = System.Drawing.Imaging.Encoder()
        encoder_quality = System.Drawing.Imaging.Encoder.Quality()
        encoder_params = System.Drawing.Imaging.EncoderParameters[0]
        encoder_param = System.Drawing.Imaging.EncoderParameter(encoder_quality, 10)
        encoder_params.Param[0] = encoder_param
        bitmap.Save(filename, System.Drawing.Imaging.ImageFormat.Jpg, encoder_params)

Hi @mitch1,

Here is a Python version of this:

import System
import Rhino
import scriptcontext as sc

def _get_image_codec_info(image_format):
    codecs = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders()
    for codec in codecs:
        if (codec.FormatID == image_format.Guid):
            return codec
    return None

def _save_jpeg_quality(bitmap, path):
    # Get an image code
    image_codec_info = _get_image_codec_info(System.Drawing.Imaging.ImageFormat.Jpeg)
    
    # Create an Encoder object based on Quality
    encoder = System.Drawing.Imaging.Encoder.Quality
    
    # Create an EncoderParameters object.
    # An EncoderParameters object has an array of EncoderParameter objects. 
    # In this case, there is only one EncoderParameter object in the array.
    encoder_params = System.Drawing.Imaging.EncoderParameters(1)
    
    encoder_param = System.Drawing.Imaging.EncoderParameter(encoder, 50)
    encoder_params.Param[0] = encoder_param
    filename = System.IO.Path.Combine(path, "test_quality_fifty.jpg");
    bitmap.Save(filename, image_codec_info, encoder_params)
    
    encoder_param = System.Drawing.Imaging.EncoderParameter(encoder, 100)
    encoder_params.Param[0] = encoder_param;
    filename = System.IO.Path.Combine(path, "test_quality_hundred.jpg");
    bitmap.Save(filename, image_codec_info, encoder_params)
    
    # Save the bitmap as a JPG file with zero quality level compression
    encoder_param = System.Drawing.Imaging.EncoderParameter(encoder, 0)
    encoder_params.Param[0] = encoder_param;
    filename = System.IO.Path.Combine(path, "test_quality_zero.jpg");
    bitmap.Save(filename, image_codec_info, encoder_params)

def test_view_capture():
    view = sc.doc.Views.ActiveView
    if not view:
        return
        
    view_capture = Rhino.Display.ViewCapture()
    view_capture.Width = view.ActiveViewport.Size.Width
    view_capture.Height = view.ActiveViewport.Size.Height
    view_capture.ScaleScreenItems = False
    view_capture.DrawAxes = False
    view_capture.DrawGrid = False
    view_capture.DrawGridAxes = False
    view_capture.TransparentBackground = False
        
    bitmap = view_capture.CaptureToBitmap(view)
    if not bitmap:
        return
        
    path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop)
    _save_jpeg_quality(bitmap, path)

if __name__ == "__main__":
    test_view_capture()

Hope this helps.

– Dale