Printing Photos using VB6 and/or .NET - vb.net

Does anyone have any code suggestions or samples for printing photos (BMP or TIFF or JPEG), using Visual Basic or .NET framework?

VB6 and .NET handle printing quite differently. These examples are the bare minumum, just to give you an idea of the process.
In VB6 you control the printer step by step:
Private Sub PrintMyPicture()
'Place to store my picture
Dim myPicture As IPictureDisp
'Load the picture into the variable
Set myPicture = LoadPicture("C:\temp\myPictureFile.bmp")
'Draw the picture on the printer, just off the edge of the page
Printer.PaintPicture myPicture, 10, 10
'Done printing!
Printer.EndDoc
End Sub
Lo and behold, your picture will come out of the default printer. the PaintPicture method accepts width, height and a few other parameters to help get the image to fit, and the Printer object gives you all sorts of info about the printer.
In .Net it's kind of the other way around. You start printing, and the printer will raise an event for each page until you tell it to stop. Every page event gives you as graphics object upon which you can draw using all of the standard System.Drawing classes and methods:
'Class variable
Private WithEvents printer As System.Drawing.Printing.PrintDocument
' Kick off the printing process. This will cause the printer_PrintPage event chain to start firing.
Public Sub PrintMyPicture()
'Set up the printer
printer.PrinterSettings.PrinterName = "MyPrinterNameInPrintersAndFaxes"
printer.Print()
End Sub
'This event will keep firing while e.HasMorePages = True.
Private Sub printer_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles printer.PrintPage
'Load the picture
Dim myPicture As System.Drawing.Image = System.Drawing.Image.FromFile("C:\temp\myPictureFile.bmp")
'Print the Image. 'e' is the Print events that the printer provides. In e is a graphics object on hwich you can draw.
'10, 10 is the position to print the picture.
e.Graphics.DrawImage(myPicture, 10, 10)
'Clean up
myPicture.Dispose()
myPicture = Nothing
'Tell the printer that there are no more pages to print. This will cause the document to be finalised and come out of the printer.
e.HasMorePages = False
End Sub
Again, there are a lot more parameters in DrawImage and the PrintDocument objects.

Related

VB.Net Print Form to PDF Printer

I am trying (and failing) right now to print a Windows Form as a PDF File in VB.Net
Now I know from doing some research that VB.Net does not have any built in function which could allow me to do this without using a third party application.
My way to get around this, was to attempt to print my Form using a PDF Printer, since logically that should work no? My issue is getting that to work properly.
This is currently my code for attempting to print:
Private Sub SelectPrinterThenPrint()
Dim PrintersDialog As New PrintDialog()
If PrintersDialog.SHowDialog(Me) = System.Forms.DialogResult.OK Then
Try
p_Document = New PrintDocument()
PrintersDialog.Document = p_Document
AddHandler p_Document.PrintPage, AddressOf HandleOnPrintPage
Catch ex As Exception
End Try
End If
End Sub
Private Sub HandleOnPrintPage(ByVal sender As Object, ByVal e As PrintPageEventArgs) Handles p_Document.PrintPage
Dim MorePagesPending = False
Dim bmp As New Bitmap(pnlContainer.Width, pnlContainer.Height)
pnlContainer.DrawToBitmap(bmp, pnlContainer.ClientRectangle)
e.Graphics.DrawImage(bmp, New Point(0,0))
If MorePagesPending Then
e.HasMorePages = True
Else
e.HasMorePages = False
End If
End Sub
The SelectPrinterThenPrint() method is called when a button on my Form is clicked. Right now I am having two issues.
1) I don't know how to setup where the file gets saved. The Print Dialog opens, and I get to select my PDF Printer, but it doesn't let me set a filename. So how do I set the filename I want to be printing to?
2) Because I can't tell if the file is actually being saved, I can't tell if I am actually setting up the print properly or not. I am trying to print the entire contents of a panel, which holds all the elements I want on my PDF file. One thing I am unsure about however, is that the form the panel is displayed in, is not the same size as the panel. The Form the panel is in has the same width, but not the same height, with the form being set up for auto scrolling. Will I get the whole Panel to print? Or just the part the is visible in the form at the time of printing?

Do I need to send ESC commands through a windows driver?

Can anyone help me.
Do I need to send printer commands when printing through a windows driver?
I am writing a windows forms application which prints out information on a label printer. This information contains an image which has a title and a barcode on it. I can create the image ok, but when I try to send it to the printer it prints completely wrong!
The Esc commands are normally handled through the Windows Driver. Here's rough example on how to print an image. You initialize PrintDocument, then use the Print method to start printing. Windows then calls the PrintPage handler, which draws on e.Graphics. e.Graphics is effectively the printer page.
Dim pd As PrintDocument
AddHandler pd.PrintPage, AddressOf printPage
' assign pd properties
pd.Print
Sub printPage(ByVal sender As Object, ByVal e As PrintPageEventArgs)
' assign img, set rectangle, determine number of pages, etc.
e.Graphics.DrawImage(img, rectangle) ' essentially draws on the printer page
e.HasMorePages = ...
end sub

VB.NET: running out of memory in System.Drawing.dll

I'm trying to teach myself programming, and I'm making an auto-graphing program that submits data to excel and returns a graph. The code is as follows:
Saving the file and exporting it:
' On program activation, establish an I/O stream for the database and load the graph
Private Sub Form1_Initialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated
' Open the database
xlWorkBook = xlApp.Workbooks.Open(DatabasePath + "Database.xlsx")
' Set the relevant worksheet
xlWorkSheet = xlWorkBook.Sheets("Sheet1")
' Set the display status of the database
xlApp.Visible = False
' Clear the picture box before exporting to prevent the compiler from accessing a file already in use
If Not (Graph.Image Is Nothing) Then
Graph.Image.Dispose()
End If
' Export the graph
xlWorkSheet.ChartObjects(1).chart.Export(FileName:=DatabasePath + ("Graph.gif"), FilterName:="gif")
' Load the saved graph image into the userform
Graph.Image = Image.FromFile(DatabasePath + ("Graph.gif"))
End Sub
It won't load the file on form activation though.
The system error comes when I utilize another piece of code, that updates relevant cells in the excel file and changes the data that is graphed. The cells are updated using a textbox change event in the userform:
Private Sub Proposed_Dollars_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Proposed_Dollars.TextChanged
' Export the data values
xlWorkSheet.Range("Q10").Value = Proposed_Dollars.Text()
' Clear the picture box before exporting to prevent the compiler from accessing a file already in use
If Not (Graph.Image Is Nothing) Then
Graph.Image.Dispose()
End If
' Export the graph
xlWorkSheet.ChartObjects(1).chart.Export(FileName:=DatabasePath + ("Graph.gif"), FilterName:="GIF")
' Load the saved graph image into the userform
Graph.Image = Image.FromFile(DatabasePath + ("Graph.gif"))
End Sub
Are there any obvious memory leaks that I'm missing that would cause the program to not load the graph into the userform picturebox?
I appreciate any help that is given.
It is fine to save the data back to the excel file, but force it to paint the graph every char is too much. What you should be doing instead is loading some variables from the excel file, allow the user to change the data, which would change the variables, then you use the Paint event to Draw the entire graph and use the variables to display the lines, rectangles, ellipses, etc... Look into GDI+ it can do everything you need.

VB.NET Tool for Image Printing - Quality Ajustments

I'm developing a tool for easy picture printing with a canon selpy cp800. The Image is printed with the following methods:
Private Sub BtnPrintClick(sender As Object, e As System.EventArgs) Handles ptnPrint.Click
If PrintDialog1.ShowDialog() = DialogResult.OK Then
pdPrintImage.Print()
End If
End Sub
Private Sub PdPrintImagePrintPage(sender As Object, e As System.Drawing.Printing.PrintPageEventArgs) Handles pdPrintImage.PrintPage
e.Graphics.DrawImage(_dPictures(_sPictures(_iActiveImage)).Picture, e.Graphics.VisibleClipBounds)
End Sub
_dPictures(_sPictures(_iActiveImage)).Picture --> object of the type image
I didn't do anything with this image. It's only loaded with the Image.FromFile() method.
Within the following image you can see my problem. This is a scan of the image printed with this method (top) and a scan of the same image printed with the windows picture viewer. You see, the first image you see the tonal errors in the background and the shadows.
Has anyone an idea to fix this?
If it isn't a bit-depth issue as Boo mentioned, it might help to set one or both of these
e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
before doing the .DrawImage.
the best quality I achieved as follows:
1) I put a picture into pdf using components iTextsharp.
2) print the pdf

How can I get the printer HDC

I have a COM component written in C++ that has a Print function. This print function takes the Printer hDC as a parameter that includes all settings to use for the print. Previously, this was called from VB6 code, and Printer.hdc would work here after setting everything on the Printer object.
The code was converted from VB6 to VB.NET, and I have figured out most of things that I need to do. The old Printer object is available through the Microsoft.VisualBasic.PowerPacks.Printing.Compability.VB6.Printer class, but the old hdc property is not supported here.
Can anyone tell me how to get this hdc?
Is this hdc the same as GetHdevmode() on a System.Drawing.Printing.PrinterSettings object?
You can get one out of the Graphics object returned by PrinterSettings.CreateMeasurementGraphics(). Use the Graphics.GetHdc() method. Don't forget ReleaseHdc() after printing.
Hdc is not the same as getdevmode, but you can do everything in .net without using hdc. If it saves time using the old code, you can get the hdc from the graphics object and use it as in nobugz's answer. But if you have a graphics object for the printer, it might be simpler to draw directly to the graphics object and skip the hdc altogether.
Here's a similar approach to the one suggested by Hans but it uses a form control. If you are using a form control anyway, this might be a cleaner approach.
Place a PrintDocument from the Windows Forms toolbox to your form.
Then add the following code to handle the print page (as an example):
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim printerhdc As IntPtr = e.Graphics.GetHdc()
' Do whatever you need to do to get the right image
XYZ.Load file(currentpagenumber)
XYZ.Render(printerhdc.ToInt64, 25, 25, Width, Height)
CurrentPageNumber += 1
If CurrentPageNumber < TotalPageCount Then
e.HasMorePages = True
Else
e.HasMorePages = False
End If
e.Graphics.ReleaseHdc(printerhdc)
End Sub
...
'Gather all the files you need and put their names in an arraylist.
'Then issue the print command
PrintDocument1.Print
' You've just printed your files
source: http://www.vbforums.com/showthread.php?247493-Good-ol-Printer-hDC
(source: http://www.vbforums.com/showthread.php?247493-Good-ol-Printer-hDC)