private static IntPtr CairoCreateImageFromFile(string imageFilePath, out int imageWidth, out int imageHeight) { IntPtr cairo_image = IntPtr.Zero; imageWidth = 0; imageHeight = 0; if (imageFilePath.Length != 0) { var tmpImgFile = System.IO.Path.GetTempPath() + TMP_IMG_NAME; using (System.Drawing.Image image = System.Drawing.Image.FromFile(imageFilePath)) { image.Save(tmpImgFile, System.Drawing.Imaging.ImageFormat.Png); cairo_image = cairo.cairo_image_surface_create_from_png(tmpImgFile); imageWidth = cairo.cairo_image_surface_get_width(cairo_image); imageHeight = cairo.cairo_image_surface_get_height(cairo_image); } } return cairo_image; } partial code this is in a loop that processes each image file I want in the PDF int imageWidth; int imageHeight; IntPtr cairo_image = CairoCreateImageFromFile(mImageFile, out imageWidth, out imageHeight); cairo_status_t status = cairo.cairo_surface_status(cairo_image); if (status != cairo_status_t.CAIRO_STATUS_SUCCESS) { cairo.cairo_surface_destroy(cairo_image); cairo_image = IntPtr.Zero; } if (cairo_image != IntPtr.Zero) { NeedCrop(ref imageWidth, ref imageHeight, (int)info.ClipRectWidthInPixels, (int)info.ClipRectHeightInPixels); // trim labels are NOT clipped to the piece. Because the clipping region has been established prior // to this function we need to save the current state, reset the clipping region and when finished // drawing the trim label restore the state if ((info.flags & Constants.TrimLabelImage) != 0) { cairo.cairo_save(cr); cairo.cairo_reset_clip(cr); } // save the current state of cr cairo.cairo_save(cr); cairo.cairo_translate(cr, locX * scale_coef, locY * scale_coef); TransformGroup tg = new TransformGroup(); tg.Children.Add(new ScaleTransform(imageSize.Width * scale_coef / imageWidth, imageSize.Height * scale_coef / imageHeight)); tg.Children.Add(imageToPieceTransform); cairo_matrix_t crTransform = new cairo_matrix_t(tg.Value.M11, tg.Value.M12, tg.Value.M21, tg.Value.M22, tg.Value.OffsetX, tg.Value.OffsetY); cairo.cairo_transform(cr, ref crTransform); if (fillPiece && tg.Inverse != null) { var pattern = cairo.cairo_pattern_create_for_surface(cairo_image); cairo.cairo_pattern_set_extend(pattern, cairo_extend_t.CAIRO_EXTEND_REPEAT); cairo.cairo_set_source(cr, pattern); // invert piece bounds var p1 = tg.Inverse.Transform(rTransfBackground.BottomLeft); var p2 = tg.Inverse.Transform(rTransfBackground.TopLeft); var p3 = tg.Inverse.Transform(rTransfBackground.TopRight); var p4 = tg.Inverse.Transform(rTransfBackground.BottomRight); cairo.cairo_move_to(cr, p1.X, p1.Y); cairo.cairo_line_to(cr, p2.X, p2.Y); cairo.cairo_line_to(cr, p3.X, p3.Y); cairo.cairo_line_to(cr, p4.X, p4.Y); cairo.cairo_close_path(cr); cairo.cairo_fill(cr); cairo.cairo_pattern_destroy(pattern); pattern = IntPtr.Zero; // DEBUG: set line color //cairo.cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); } else { // crop image - move out mask cairo.cairo_set_source_surface(cr, cairo_image, -info.clipRectLeft, -info.clipRectTop); // mask cairo.cairo_rectangle(cr, 0, 0, imageWidth, imageHeight); // fill cairo.cairo_fill(cr); // DEBUG: set line color cairo.cairo_set_source_rgb(cr, 0.0, 0.0, 1.0); } cairo.cairo_surface_destroy(cairo_image); cairo_image = IntPtr.Zero; // DEBUG: draw image position //cairo.cairo_set_line_width(cr, 0.4); //cairo.cairo_rectangle(cr, 0, 0, imageWidth, imageHeight); //cairo.cairo_stroke(cr); // if trim label restore the state (clipping region) if ((info.flags & Constants.TrimLabelImage) != 0) { cairo.cairo_restore(cr); // delete the "temp" label file File.Delete(mImageFile); } // restore the saved state of cr cairo.cairo_restore(cr); }