UPDATE: Source code now available here and on CodePlex.
Here’s a small WPF utility to help make ad-hoc photo printing a little easier.
It borrows a couple of features from Picasa / iPhoto, but with a few notable differences:
- No need to import your photos into a “walled” library (great if your photos are on a network share like mine, or just want an ad-hoc print from a memory card).
- Never changes the source image and doesn’t require version history.
- All operations are additive and vector-based. Currently supports rotate (90° clockwise), crop (with aspect ratios) and straighten (up to 45° each way).
- It’s fast (no need to “Apply” changes or undo them later).
- Potential to add bitmap / shader effects (designed with it in mind, but not implemented yet)…
You should be able to get borderless prints out of it easily enough (or print to XPS for further processing). It uses the standard print dialog and works fine on my HP Photosmart C7250 (haven’t tested elsewhere yet). I plan to add extra options like “Save as…” and “Copy to clipboard” when time (and inclination) allows…
You can get the app here (only 45kb unzipped!). Note: You’ll need .NET 3.5 SP1. Later I’ll either post source code here or maybe put it on Codeplex (if any interest from you guys).
Enjoy!
18 responses so far ↓
Alvin Ashcraft // July 29, 2008 at 6:59 am |
Cool stuff! I would be interested in checking out the source. You should post to CodePlex.
Dew Drop - July 29, 2008 | Alvin Ashcraft's Morning Dew // July 29, 2008 at 7:32 am |
[...] WPF Photo Print (.NET 3.5 SP1) (Chris Cavanagh) [...]
Vijay // August 14, 2008 at 6:08 am |
Can you share the source code of print functionality?
Chris Cavanagh // August 19, 2008 at 11:09 pm |
Alvin, Vijay – I’ll get the source published as soon as I clean it up (need to remove some obsolete code). Until then, here’s a snip of the printing code:
var image = new TransformedImage { Drawing = transformable.Drawing };
var capabilities = dialog.PrintQueue.GetPrintCapabilities( dialog.PrintTicket );
var pageAspect = capabilities.PageImageableArea.ExtentWidth / capabilities.PageImageableArea.ExtentHeight;
if ( ( transformable.AspectRatio > 1 ) != ( pageAspect > 1 ) )
{
image.LayoutTransform = new RotateTransform( 90, 0.5, 0.5 );
}
var size = new Size( capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight );
image.Measure( size );
image.Arrange( new Rect(
new Point( capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight ),
size ) );
dialog.PrintVisual( image, transformable.Name );
The TransformedImage class is just a WPF control that renders a Drawing inside an image (using a DrawingBrush). All the photo composition is done with Drawing objects.
The only other thing this code does is auto-rotate the final image before printing, to match the paper orientation (I’m not actually sure if it needs to do this; maybe the printer can handle that itself).
Hope this helps!
WPF Photo Print - Source code « Chris Cavanagh’s Blog // August 22, 2008 at 1:12 am |
[...] 22, 2008 · No Comments You can get the source code for my WPF Photo Print utility here. There are a couple obsolete files in there, but you can consider those my [...]
WiredPrairie - Some WPF stuff… // August 22, 2008 at 7:53 pm |
[...] From Chris, WPF Photo Print. [...]
Rick Engle // October 17, 2008 at 2:51 pm |
Hey Chris this is tremedous! Does your code also support resizing an image and saving it?
Rick
Chris Cavanagh // October 17, 2008 at 2:56 pm |
Rick – It doesn’t yet, but it’d be very easy to implement. It’s on my todo list…
(I’ll probably put it on CodePlex)
Rick Engle // October 27, 2008 at 8:12 pm |
Awesome, looking forward to it if you get a chance!
Rick
Ashish // March 10, 2009 at 12:36 am |
Hi,
I am new to Silverlight.
Can anyone suggest how can I use this code with a silverlight application?
Ashish
Chris Cavanagh // March 10, 2009 at 8:09 am |
Hi Ashish – Most of the code is built around WPF’s Drawing classes (DrawingGroup, GeometryDrawing etc). Often it’s possible to migrate classes from WPF to Silverlight with some help from Reflector (now maintained by Red Gate). Let me know if you plan to give that a try; I might be able to help a bit
Ashish // March 10, 2009 at 11:22 pm |
Hi Chris,
Thanks for a quick reply. What i want is, the project which you have created in WPF i want to create same application using Silverlight. What I tried to do is copied all the classes to silverlight application. I’m getting an error while trying to add reference to the System.Printing. It says “You can’t add a reference to System.Printing.dll as it was not built against the Silverlight runtime. Silverlight projects will only work with Silverlight assemblies.”. Could you please tell me how can I resolve this issue.
Thanks in advance.
Ashish
ricardo // September 17, 2009 at 2:04 pm |
Hi
I want to know how can separate the photo cropping (selection) part into a separate component, but everything is too much related, can you give me a hint
Chris Cavanagh // September 17, 2009 at 2:43 pm |
ricardo – You probably want to look in these places:
Preview.xaml – Find the local:Crop DataTemplate. That renders the opaque area (as an OpacityMask). It databinds to the Crop transformation (Crop.cs)
Preview.xaml.cs – Creates an instance of thhe CropAdorner (in cropSelect_Loaded) and attaches it to the preview. Also handles mouse events and adjusts the adorner to match.
CropAdorner.cs – (based on darrelp’s project on CodeProject: http://www.codeproject.com/KB/WPF/CropAdorner.aspx) – Renders the drag handles.
Hope this helps!
ricardo // September 17, 2009 at 3:13 pm |
mm it is getting really complicate to split it…
because I need to create a crop adorner which I can supply an frameworkelement to be cropped, but it seems that you are passing a transform item, and this is related to various classes that dont need….
any more hints?
ricardo // September 17, 2009 at 3:35 pm |
can you explain me this line
its at main windows, I dont get where is the CurrentItem..Transformations.CurrentItem comes
Chris Cavanagh // September 21, 2009 at 1:31 pm |
Ashish – Sorry for my slow reply! Silverlight provides very little support for printing right now (but apparently this will improve in Silverlight 4). One option might be to send the image and transformation details to your server and let it return a rendered image; from there the user should be able to print using their browser…
Chris Cavanagh // September 21, 2009 at 1:34 pm |
Ricardo – Can you email me the details? (didn’t show up in blog comment)… (ricardo at chriscavanagh.com). CurrentItem.Transformations.CurrentItem is just referening the selected transformation in the UI (the first CurrentItem will be the image, Transformations.CurrentItem will be the selected transformation for that image).