I'm porting an C# .NET application to Mono .NET for executing in OSX. Part of the application involves printing an image. Fairly easy in .NET and boils down to primarily
e.Graphics.DrawImage(img, new Rectangle(x, y, printSize.Width, printSize.Height));
in the PrintDocument's PrintPage event. Mono does not have a full implementation of System.Drawing.Printing so it seems that the best way to go about doing this is using GtkSharp. I've found some examples online as to how to print text using a Gtk.PrintOperation. PrintOperation has an event DrawPage which should be similar to PrintPage, however I could only find how to use PangoSharp to print text in this event.
Enough explaining what I do know, I think the question is fairly straight forward. I hope somebody can be of help as GtkSharp's printing is not well documented. If there is a better way to do this outside GtkSharp, I am all ears.
Many thanks.
EDIT
So I've managed to get something printing, however, it is always a blank page. Here is the code:
var print = new PrintOperation();
print.BeginPrint += (obj, args) => { print.NPages = 1; };
print.DrawPage += (obj, args) => {
PrintContext context = args.Context;
Cairo.Context cr = context.CairoContext;
var imageSurface = new Cairo.ImageSurface(printImage.FileName);
cr.MaskSurface(imageSurface, 0, 0);
};
print.EndPrint += (obj, args) => { };
print.Run(PrintOperationAction.Print, null);
I've been struggling with Gtk.PrintOperation for a couple of days, but with your post it finally came together. The following changes to your code example works for me:
var print = new PrintOperation();
print.BeginPrint += (obj, args) => { print.NPages = 1; };
print.DrawPage += (obj, args) => {
PrintContext context = args.Context;
Cairo.Context cr = context.CairoContext;
var imageSurface = new Cairo.ImageSurface(printImage.FileName);
int w = imageSurface.Width;
int h = imageSurface.Height;
cr.Scale(256.0/w, 256.0/h);
cr.SetSourceSurface(imageSurface, 0,0);
cr.Paint();
};
print.EndPrint += (obj, args) => { };
print.Run(PrintOperationAction.Print, null);
Also, it only seems to work for PNG type images.
With a little manipulation of Dave Black's answer, I found a way to print any image type. Supposedly, you should be able to load any image type into a Pixbuf and use the Gdk CairoHelper to paint the Pixbuf on the CairoContext. I had issues with loading from file to Pixbuf when the type was not a PNG, so I used System.Drawing.Image to load it into a byte array first.
Also, make sure this occurs on the main thread of the application. If your code is occurring on a different thread, call
Gtk.Application.Invoke(delegate {
to invoke on the main thread.
var imageBit = default(byte[]);
var image = System.Drawing.Image.FromFile(fileName);
using (var memoryStream = new MemoryStream()) {
image.Save(memoryStream, ImageFormat.Png);
imageBit = memoryStream.ToArray();
}
var print = new PrintOperation();
print.BeginPrint += (obj, a) => { print.NPages = 1; };
print.DrawPage += (obj, a) => {
using (PrintContext context = a.Context) {
using (var pixBuf = new Gdk.Pixbuf(imageBit, image.Width, image.Height)) {
Cairo.Context cr = context.CairoContext;
cr.MoveTo(0, 0);
Gdk.CairoHelper.SetSourcePixbuf(cr, pixBuf, image.Width, image.Height);
cr.Paint();
((IDisposable) cr).Dispose();
}
}
};
print.EndPrint += (obj, a) => { };
print.Run(PrintOperationAction.Print, null);
来源:https://stackoverflow.com/questions/9459685/how-to-print-image-with-gtksharp