@@ -466,9 +466,35 @@ impl<'a> RenderContext for CoreGraphicsContext<'a> {
466466 ) ) ;
467467 }
468468
469- match full_image. cropped ( src_cgrect) {
470- Some ( image) => Ok ( CoreGraphicsImage :: from_cgimage_and_ydir ( image, self . y_down ) ) ,
471- None => Err ( Error :: InvalidInput ) ,
469+ let cropped_image_result = full_image. cropped ( src_cgrect) ;
470+ if let Some ( image) = cropped_image_result {
471+ // CGImage::cropped calls CGImageCreateWithImageInRect to set the bounds of the image,
472+ // but it does not affect the underlying image data. This causes issues when using the
473+ // captured images if the image's width does not match the original context's row size.
474+ // To fix this, we create a new image-sized bitmap context, paint the image to it, and
475+ // then re-capture. This forces coregraphics to resize the image to its specified bounds.
476+ let cropped_image_size = Size :: new ( src_cgrect. size . width , src_cgrect. size . height ) ;
477+ let cropped_image_rect = Rect :: from_origin_size ( Point :: ZERO , cropped_image_size) ;
478+ let cropped_image_context = core_graphics:: context:: CGContext :: create_bitmap_context (
479+ None ,
480+ cropped_image_size. width as usize ,
481+ cropped_image_size. height as usize ,
482+ 8 ,
483+ 0 ,
484+ & core_graphics:: color_space:: CGColorSpace :: create_device_rgb ( ) ,
485+ core_graphics:: base:: kCGImageAlphaPremultipliedLast,
486+ ) ;
487+ cropped_image_context. draw_image ( to_cgrect ( cropped_image_rect) , & image) ;
488+ let cropped_image = cropped_image_context
489+ . create_image ( )
490+ . expect ( "Failed to capture cropped image from resize context" ) ;
491+
492+ Ok ( CoreGraphicsImage :: from_cgimage_and_ydir (
493+ cropped_image,
494+ self . y_down ,
495+ ) )
496+ } else {
497+ Err ( Error :: InvalidInput )
472498 }
473499 }
474500
0 commit comments