::::::::: PowerShell :::::::::
Tuesday, February 14, 2006
  [MSH] print-image
Your boss comes at your desk with a pile of CDs filled with high quality tiff images(roughly 20000 x 20000 pixels)
He tells you to print all the image files fit into a "letter" sized paper in 2 days

Well, that sort of stuff happend to me...

Man, was I frusted...

But that's when MSH came into rescue~
Well, the first thing that came up in my head was, "out-printer" cmdlet.
So I tried the following

MSH>$bitmap = new-object System.Drawing.Bitmap c:\test.tif
MSH>out-printer -printer "Adobe PDF" -in $bitmap


Voila. Now i was excited to see a picture in PDF format through "out-printer".
Wrong!

All I saw in the generated PDF file was

Tag :
PhysicalDimension : {Width=14454, Height=21957}
Size : {Width=14454, Height=21957}
Width : 14454
Height : 21957
HorizontalResolution : 1016
VerticalResolution : 1016
Flags : 77888
RawFormat : [ImageFormat: b96b3cb1-0728-11d3-9d7b-0000f81ef32e]
PixelFormat : Format1bppIndexed
Palette : System.Drawing.Imaging.ColorPalette
FrameDimensionsList : {7462dc86-6180-4c7e-8e3f-ee7333a7a483}
PropertyIdList : {256, 257, 258, 259, 262, 270, 273, 277, 278, 279, 282, 283, 32781}
PropertyItems : {256, 257, 258, 259, 262, 270, 273, 277, 278, 279, 282, 283, 32781}


, which is data you see just typing "MSH>$bitmap" in console.

Gosh, was I frusted, again. I looked into "out-printer" help page if there was some kind of "-encoding" option to print binary files(images) but there wans't any...

I resorted to using System.Drawing.Printing.PrintDocument

Well, using that Class, printing is an image is a breezy job
So i created a cmdlet called "print-image" which takes an image name and print it

Here is the usage of the cmdlet

print-image "image name" [printer name] [fit image to paper]


The cmdlet takes the mandatory parameter "image name" with optional printer to print to and whether image size should fit on a paper

Following is how the cmdlet can be used

MSH> ls *.tif | foreach { print-image $_ }


Well and that's exactly what i did... :)







function print-image {
param([string]$imageName = $(throw "Enter image name to print"),
[string]$printer = "",
[bool]$fitImageToPaper = $true)

trap { break; }

# check out Lee Holmes' blog(http://www.leeholmes.com/blog/HowDoIEasilyLoadAssembliesWhenLoadWithPartialNameHasBeenDeprecated.aspx)
# on how to avoid using deprecated "LoadWithPartialName" function
# To load assembly containing System.Drawing.Printing.PrintDocument
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

# Bitmap image to use to print image
$bitmap = $null

$doc = new-object System.Drawing.Printing.PrintDocument
# if printer name not given, use default printer
if ($printer -ne "") {
$doc.PrinterSettings.PrinterName = $printer
}

$doc.DocumentName = [System.IO.Path]::GetFileName($imageName)

$doc.add_BeginPrint({
Write-Host "==================== $($doc.DocumentName) ===================="
})

# clean up after printing...
$doc.add_EndPrint({
if ($bitmap -ne $null) {
$bitmap.Dispose()
$bitmap = $null
}
Write-Host "xxxxxxxxxxxxxxxxxxxx $($doc.DocumentName) xxxxxxxxxxxxxxxxxxxx"
})

# Adjust image size to fit into paper and print image
$doc.add_PrintPage({
Write-Host "Printing $imageName..."

$g = $_.Graphics
$pageBounds = $_.MarginBounds
$img = new-object Drawing.Bitmap($imageName)

$adjustedImageSize = $img.Size
$ratio = [double] 1;

# Adjust image size to fit on the paper
if ($fitImageToPaper) {
$fitWidth = [bool] ($img.Size.Width > $img.Size.Height)
if (($img.Size.Width -le $_.MarginBounds.Width) -and
($img.Size.Height -le $_.MarginBounds.Height)) {
$adjustedImageSize = new-object System.Drawing.SizeF($img.Size.Width, $img.Size.Height)
} else {
if ($fitWidth) {
$ratio = [double] ($_.MarginBounds.Width / $img.Size.Width);
} else {
$ratio = [double] ($_.MarginBounds.Height / $img.Size.Height)
}

$adjustedImageSize = new-object System.Drawing.SizeF($_.MarginBounds.Width, [float]($img.Size.Height * $ratio))
}
}

# calculate destination and source sizes
$recDest = new-object Drawing.RectangleF($pageBounds.Location, $adjustedImageSize)
$recSrc = new-object Drawing.RectangleF(0, 0, $img.Width, $img.Height)

# Print to the paper
$_.Graphics.DrawImage($img, $recDest, $recSrc, [Drawing.GraphicsUnit]"Pixel")

$_.HasMorePages = $false; # nothing else to print
})

$doc.Print()
}





Oh yeah, I would appreciate it if anyone can tell me how i can format the code to fit on to the site :)

Tags :
 
Comments:
Nice solution,
b.t.w. did you think about landscape I think there is a rotating script on the monad team blog

greetings /\/\o\/\/

P.S. I formated my blog to the code ;-(
 
Thanks for the info there, /\/\o\/\/.

Well, I could modify the cmdlet to support landscape printing as well as duplex, and collate since they are part of PrinterSettings's properties.

Extending would be fun but, I think i will be converting the script into a Snapin if I need support more features :)
 
I did see you last post,

Guess you did feel like it;-)
thx,

gr /\/\o\/\/
 
Nice!!

But... when I try it on a multipage tif it only prints the first page. Any ideas why?

//Rob
 
*bump* Any ideas on loading in pages from a multipage tiff?
 
It can be use on pdf convert to a multipage tiff!
 
Exception calling "Print" with "0" argument(s): "Exception calling ".ctor" with "1" argument(s): "Parameter is
not valid.""

Why would I be getting this?
 
Also getting this, curious if anyone ever found a resolution.

Exception calling "Print" with "0" argument(s): "Exception calling ".ctor" with "1" argument(s): "Parameter is
not valid.""
 
Got this to work, thank you. See below for some info:

Print-Image -ImageName C:\Temp\image.png -printer Xerox6055Sales

My missing piece was the include the full path to the image with the ImageName parameter.

Can confirm this worked. Hope it helps.
 
Updated it to do multipage TIFFs. I am sure mine can be improved upon. Thanks for the base script!
------------------------------------------------------------------
$rootdir = 'C:\Temp\pdf2tiff\'
$File = 'SomeMultiPage.tiff'
##Set path to print to PDF before merge
$TextDocumentPath = ($rootdir+$File )
# Get the path to the TIFF image file
$imagePath = $TextDocumentPath

# Create a PrintDocument object
$printDocument = New-Object System.Drawing.Printing.PrintDocument
$printDocument.DocumentName = $TextDocumentPath
# Set the printer name to 'Microsoft Print to PDF'
$printDocument.PrinterSettings.PrinterName = 'Microsoft Print to PDF'
$printDocument.PrinterSettings.PrintToFile = $true
$streamToPrint = New-Object System.IO.StreamReader $TextDocumentPath
# Set the page settings to fit the image to the page
$printDocument.DefaultPageSettings.Landscape = $false

#Set file export location
$file=[io.fileinfo]$TextDocumentPath
$pdf= [io.path]::Combine($file.DirectoryName, $file.BaseName) + '.pdf'
$printDocument.PrinterSettings.PrintFileName = $pdf
# Add an event handler for the PrintPage event and set page # outside handler
$script:pageNumber=0
$printDocument.add_PrintPage({
param($sender, $e)

# Load the image into a Bitmap object
$image = New-Object System.Drawing.Bitmap $imagePath
$image.SelectActiveFrame($image.FrameDimensionsList[0],$script:pageNumber)
$g = $e.Graphics
$pageBounds = $e.MarginBounds

$adjustedImageSize = $image.Size
$ratio = [double] 1;

# Adjust image size to fit on the paper

$fitWidth = [bool] ($image.Size.Width > $image.Size.Height)
if (($image.Size.Width -le $e.MarginBounds.Width) -and ($image.Size.Height -le $e.MarginBounds.Height)) {
$adjustedImageSize = new-object System.Drawing.SizeF($image.Size.Width, $image.Size.Height)
} else {
if ($fitWidth) {
$ratio = [double] ($e.MarginBounds.Width / $image.Size.Width);
} else {
$ratio = [double] ($e.MarginBounds.Height / $image.Size.Height)
}

$adjustedImageSize = new-object System.Drawing.SizeF($e.MarginBounds.Width, [float]($image.Size.Height * $ratio))
}

# calculate destination and source sizes
$recDest = new-object Drawing.RectangleF($pageBounds.Location, $adjustedImageSize)
$recSrc = new-object Drawing.RectangleF(0, 0, $image.Width, $image.Height)

# Print to the paper
$e.Graphics.DrawImage($image, $recDest, $recSrc, [Drawing.GraphicsUnit]"Pixel")
# Increment the page number
$script:pageNumber++

# Set the HasMorePages property based on the number of pages in the image
$e.HasMorePages = $script:pageNumber -lt $image.GetFrameCount([System.Drawing.Imaging.FrameDimension]::Page)
})

# Print the document
$printDocument.Print()
$streamToPrint.Close()
$printDocument.Dispose()

 
Above Script update posted by Sam F. ^^
 
Post a Comment



<< Home
Let's get lazy with PowerShell!

Name:
Location: Flushing, NY, United States

Experimenting with a different format of blogs...

Links
ARCHIVES
10/01/2005 - 11/01/2005 / 11/01/2005 - 12/01/2005 / 12/01/2005 - 01/01/2006 / 01/01/2006 - 02/01/2006 / 02/01/2006 - 03/01/2006 / 03/01/2006 - 04/01/2006 / 04/01/2006 - 05/01/2006 / 05/01/2006 - 06/01/2006 / 06/01/2006 - 07/01/2006 / 07/01/2006 - 08/01/2006 / 08/01/2006 - 09/01/2006 / 10/01/2006 - 11/01/2006 / 11/01/2006 - 12/01/2006 /


Powered by Blogger