VB.NET resize and crop images - vb.net

i have a VSTO for powerpoint and want to resize images so they are the same size as the slide. a sample image i have is 1000x300 and the slide is 960x540. so this is the code i have:
_W=960
_H=540
Dim img As Image = System.Drawing.Bitmap.FromFile(file1)
OldRect = New RectangleF(233, 0, 533, 300) ' calculated values to crop left and right
NewRect = New RectangleF(0, 0, _W, _H)
Dim bmp As Bitmap = New Bitmap(img, _W, _H)
Dim g As Graphics = Graphics.FromImage(bmp)
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
g.DrawImage(img, NewRect, OldRect, GraphicsUnit.Pixel)
img.Save(file2, Imaging.ImageFormat.Png)
but when i look at file2 it's the same 1000x300 file as the original. what am i missing here?

#plutonix; you're spot on. i was under the wrong impression that DrawImage would replace the image it was offered. but saving the bitmap the graphics object was created with produced the intended image.
bmp.Save(file2, Imaging.ImageFormat.Png)
works perfect. thanks!

The answer posted here is good but there is one major problem of quality that need to be addressed. In most cased you have to Crop Image and Maintain the Quality so in that regard, I have improved the crop feature of a sample and posted below is the link. This demo is in VB.NET but you can easily understand the concept and make adjustments.
http://www.mediafire.com/file/70rmlpcdjyxo8gc/ImageCroppingDemo_-_Maintain_Image_Quality.zip/file
CODES For Cropping (VB.NET)
Dim cropX As Integer
Dim cropY As Integer
Dim cropWidth As Integer
Dim cropHeight As Integer
Dim oCropX As Integer
Dim oCropY As Integer
Dim cropBitmap As Bitmap
Dim Loadedimage As Image
Public cropPen As Pen
Public cropPenSize As Integer = 1 '2
Public cropDashStyle As Drawing2D.DashStyle = Drawing2D.DashStyle.Solid
Public cropPenColor As Color = Color.Yellow
Private Sub crobPictureBox_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles crobPictureBox.MouseDown
Try
If e.Button = Windows.Forms.MouseButtons.Left Then
cropX = e.X
cropY = e.Y
cropPen = New Pen(cropPenColor, cropPenSize)
cropPen.DashStyle = DashStyle.DashDotDot
Cursor = Cursors.Cross
End If
crobPictureBox.Refresh()
Catch exc As Exception
End Try
End Sub
Dim tmppoint As Point
Private Sub crobPictureBox_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles crobPictureBox.MouseMove
Try
If crobPictureBox.Image Is Nothing Then Exit Sub
If e.Button = Windows.Forms.MouseButtons.Left Then
crobPictureBox.Refresh()
cropWidth = e.X - cropX
cropHeight = e.Y - cropY
crobPictureBox.CreateGraphics.DrawRectangle(cropPen, cropX, cropY, cropWidth, cropHeight)
End If
' GC.Collect()
Catch exc As Exception
If Err.Number = 5 Then Exit Sub
End Try
End Sub
Private Sub crobPictureBox_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles crobPictureBox.MouseUp
Try
Cursor = Cursors.Default
Try
If cropWidth < 1 Then
Exit Sub
End If
Dim smallWidthPercentage As Single = (cropWidth / crobPictureBox.Width) * 100
Dim smallHeightPercentage As Single = (cropHeight / crobPictureBox.Height) * 100
Dim smallXPercentage As Single = (cropX / crobPictureBox.Width) * 100
Dim smallYPercentage As Single = (cropY / crobPictureBox.Height) * 100
smallHeightPercentage += 10
smallYPercentage -= 10
Dim Widthdifference As Integer = Loadedimage.Width - crobPictureBox.Width
Dim HeightDifference As Integer = Loadedimage.Height - crobPictureBox.Height
Dim rect As Rectangle
rect = New Rectangle((smallXPercentage / 100) * Loadedimage.Width, (smallYPercentage / 100) * Loadedimage.Height, (smallWidthPercentage / 100) * Loadedimage.Width, (smallHeightPercentage / 100) * Loadedimage.Height)
Dim bit As Bitmap = New Bitmap(Loadedimage, Loadedimage.Width, Loadedimage.Height)
cropBitmap = New Bitmap(Loadedimage, (smallWidthPercentage / 100) * Loadedimage.Width, (smallHeightPercentage / 100) * Loadedimage.Height)
Dim g As Graphics = Graphics.FromImage(cropBitmap)
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
g.DrawImage(bit, 0, 0, rect, GraphicsUnit.Pixel)
PreviewPictureBox.Image = cropBitmap
Catch exc As Exception
End Try
Catch exc As Exception
End Try
End Sub

Related

VB.NET Print Large Image on Multiple Pages

i have a problem printing an large image over multiple Pages. I have scanned A4 Documents with 1-x Pages and they put together as one long image. I have to rescale Image to fit in width on A4 and to print with as many pages as on image are. There ist my code, can't achieve this, printing only first page. Any help woud be aprechiated. Thanks! (i'm a beginner...)
Imports System.Drawing.Printing
Imports System.Drawing.Imaging
Imports System.IO
Public Class Form1
Dim Bmp As Bitmap
dim pageNum As Int32 = 0
Private Sub PrintDocument4_PrintPage(ByVal sender As Object, ByVal e As PrintPageEventArgs) Handles PrintDocument4.PrintPage
Dim WidthRatio As Double = e.MarginBounds.Width / Bmp.Width
Dim maxpagenum As Int32 = Math.Ceiling(Bmp.Height / e.MarginBounds.Height * WidthRatio)
Debug.WriteLine(maxpagenum)
Debug.WriteLine(e.MarginBounds.Height)
Dim piece As New Bitmap(CInt(e.MarginBounds.Width / WidthRatio), CInt(e.MarginBounds.Height / WidthRatio))
Dim dest_rect As New Rectangle(0, 0, CInt(e.MarginBounds.Width / WidthRatio), CInt(e.MarginBounds.Height / WidthRatio))
Using gr As Graphics = Graphics.FromImage(piece)
Dim source_rect As New Rectangle(0, 0, CInt(e.MarginBounds.Width / WidthRatio), CInt(e.MarginBounds.Height / WidthRatio))
For i As Integer = 1 To maxpagenum
source_rect.X = 0
' Copy the piece of the image.
gr.DrawImage(Bmp, dest_rect, source_rect, _
GraphicsUnit.Pixel)
'piece.Save("Bmp" & i & ".jpg", ImageFormat.Bmp)
e.Graphics.DrawImage(piece, 0, source_rect.Y, CInt(piece.Width * WidthRatio), CInt(piece.Height * WidthRatio))
pageNum += 1
source_rect.Y += CInt(e.MarginBounds.Height / WidthRatio)
If pageNum < maxpagenum Then
e.HasMorePages = True
Else
pageNum = 0
End If
Next
End Using
End Sub
Private Sub Button9_Click(sender As Object, e As EventArgs) Handles Button9.Click
If ListBox1.SelectedItem IsNot Nothing Then
Dim selItem As String = ListBox1.SelectedItem.ToString()
Dim fs1 As System.IO.FileStream
fs1 = New System.IO.FileStream(selItem, IO.FileMode.Open, IO.FileAccess.Read)
Bmp = New Bitmap(System.Drawing.Image.FromStream(fs1))
fs1.Close()
PrintDocument4 = New PrintDocument
With PrintDialog1
.AllowCurrentPage = False
.AllowPrintToFile = False
.AllowSelection = False
.AllowSomePages = False
.Document = PrintDocument4
.PrinterSettings.DefaultPageSettings.Margins.Top = 15
.PrinterSettings.DefaultPageSettings.Margins.Bottom = 15
.PrinterSettings.DefaultPageSettings.Margins.Left = 15
.PrinterSettings.DefaultPageSettings.Margins.Right = 15
End With
If PrintDialog1.ShowDialog = DialogResult.OK Then
PrintDocument4.PrinterSettings = PrintDialog1.PrinterSettings
AddHandler PrintDocument4.PrintPage, AddressOf PrintDocument4_PrintPage
PrintDocument4.Print()
End If
End If
End Sub

A Graphics object cannot be created from an image that has an indexed pixel format

I have a program that when you click on picturebox1, it transfers the image inside it to picturebox2. Then I have an interpolation code to modify it to a nearestneighbor pixel rendering. It also draws a pixel grid on picturebox2 to line up around the pixels. I have picturebox2 set to stretch image. I tried 2 different methods of drawing on the picturebox2. I am having a problem converting the image back to the right size to transfer it back to picturebox1 after its been edited with the paintbrush.
CODE:
Imports System.Windows.Forms
Imports System.Drawing
Imports System
Imports System.IO
Public Class Form1
Dim Brush = Brushes.Black
Dim COLOR1 As Color
Dim BMP As Bitmap
Dim Draw As Boolean
CODE: when you click on the picturebox1(topleft) it transfers its image to picturebox2(canvaseditor) does the grid draw, interpolate mode etc.
Private Sub topleft_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles topleft.Click
tiledcanvas.BackgroundImage = topleft.Image
Label1.Text = "Top-Left"
'CANVAS PIXEL GRID CODE
If topleft.Image Is Nothing Then
Else
canvaseditor.Image = Nothing
canvaseditor.Image = topleft.Image
canvaseditor.Width = topleft.Width * 8 + 1
canvaseditor.Height = topleft.Height * 8 + 1
'load and draw the image(s) once
BackgroundImage1 = New Bitmap(topleft.Image)
bmpNew = New Bitmap(canvaseditor.Width * scaleFactor, canvaseditor.Height * scaleFactor)
Using g As Graphics = Graphics.FromImage(bmpNew)
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half
g.DrawImage(BackgroundImage1, 0, 0, bmpNew.Width, bmpNew.Height)
End Using
canvaseditor.Focus()
GroupBox13.Focus()
End If
End Sub
CODE: the paintbrush code, the mousedown, mousemove, and mouseup events on picturebox2(canvaseditor)
Private Sub canvaseditor_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles canvaseditor.MouseMove
If Draw = True Then
PaintBrush(e.X, e.Y)
Else
End If
'If down = True Then
'canvaseditor.CreateGraphics.FillRectangle(Brush, e.X, e.Y, 8, 8)
'End If
' LocalMousePosition = canvaseditor.PointToClient(Cursor.Position)
'Dim X As Integer
'Dim Y As Integer
'If LocalMousePosition.X > 0 And LocalMousePosition.X < 9 Then
'X = 1
' ElseIf LocalMousePosition.X > 8 And LocalMousePosition.X < 17 Then
'X = 2
'ElseIf LocalMousePosition.X > 16 And LocalMousePosition.X < 25 Then
'X = 3
'End If
'Label6.Text = (X & ", " & Y)
End Sub
Private Sub PaintBrush(ByVal X As Integer, ByVal Y As Integer)
Using g As Graphics = Graphics.FromImage(canvaseditor.Image)
g.FillRectangle(New SolidBrush(Color.Black), New Rectangle(X, Y, 6, 6))
End Using
canvaseditor.Refresh()
End Sub
Private Sub canvaseditor_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles canvaseditor.MouseDown
'down = True
'If down = True Then
'Dim NEWBMP As New Bitmap(topleft.Width, topleft.Height)
'Dim graph As Graphics = Graphics.FromImage(NEWBMP)
' graph.FillRectangle(Brush, e.X, e.Y, 8, 8)
'topleft.Image = NEWBMP
'End If
'down = True
'If down = True Then
'canvaseditor.CreateGraphics.FillRectangle(Brush, e.X, e.Y, 8, 8)
'End If
Draw = True
PaintBrush(e.X, e.Y)
End Sub
Private Sub canvaseditor_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles canvaseditor.MouseUp
Draw = False
End Sub
and heres the first paint sub i made:
Private Sub canvaseditor_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles canvaseditor.Paint
If Not bmpNew Is Nothing Then
e.Graphics.DrawImage(bmpNew, 0, 0)
End If
Dim g As Graphics = e.Graphics
Dim pn As New Pen(Color.DimGray) '~~~ color of the lines
Dim x As Integer
Dim y As Integer
Dim intSpacing As Integer = 8 '~~~ spacing between adjacent lines
'~~~ Draw the horizontal lines
x = canvaseditor.Width
For y = 0 To canvaseditor.Height Step intSpacing
g.DrawLine(pn, New Point(0, y), New Point(x, y))
Next
'~~~ Draw the vertical lines
y = canvaseditor.Height
For x = 0 To canvaseditor.Width Step intSpacing
g.DrawLine(pn, New Point(x, 0), New Point(x, y))
Next
End Sub
hoping this is understandable so someone can point me in the right direction. thanks.

Resizing drawn rectangle on Picturebox relative to image using Zoom

I have a Picturebox that I can draw a rectangle on and I have it so that the rectangle dimensions, in percent, are logged so that if the size of the form changes, then so does the rectangle size (see code below the text)
However, when I have the Picturebox in "Zoom" mode, the rectangle does not match up when resizing (see here: First one, with corners on defined points on image http://i1262.photobucket.com/albums/ii602/bmgh85/Size1.png and then second one after resizing the form http://i1262.photobucket.com/albums/ii602/bmgh85/Size2.png
It works fine in "Stretch" mode, but that skews the images, which is no use to me (I need to keep the proportions). How can I manipulate my code to get it to work as intended?
Private x, y As Integer
Private Rct As New Rectangle(0, 0, 0, 0)
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
x = e.X
y = e.Y
End If
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left Then
Rct.X = Math.Min(x, e.X)
Rct.Y = Math.Min(y, e.Y)
Rct.Height = Math.Abs(e.Y - y)
Rct.Width = Math.Abs(e.X - x)
PictureBox1.Refresh()
PictureBox1.Tag = calculatePercent(Rct.X, Rct.Y, Rct.Height, Rct.Width, PictureBox1)
End If
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
MsgBox(PictureBox1.Tag)
Dim lst1 As List(Of Int32) = returnPercent(PictureBox1.Tag)
For i = 0 To lst1.Count - 1
MsgBox(lst1(i))
Next
End Sub
Private Sub PictureBox1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.DrawRectangle(Pens.Red, Rct)
End Sub
Function calculatePercent(ByVal X As Long, Y As Long, Ht As Long, Wth As Long, pBox As PictureBox)
Dim wPercent As Long = 100 * Wth / pBox.Width
Dim hPercent As Long = 100 * Ht / pBox.Height
Dim yPercent As Long = 100 * Y / pBox.Height
Dim xPercent As Long = 100 * X / pBox.Width
Return "X:" & xPercent & ", Y:" & yPercent & ", Ht:" & hPercent & ", Wth:" & wPercent
End Function
Function returnPercent(ByVal myTag As String)
Dim lst As New List(Of Int32)
Dim getX As String = getNum(Mid(myTag, InStr(myTag, "X:"), InStr(myTag, ", Y:") - InStr(myTag, "X:")))
Dim getY As String = getNum(Mid(myTag, InStr(myTag, ", Y:"), InStr(myTag, ", Ht:") - InStr(myTag, ", Y:")))
Dim getH As String = getNum(Mid(myTag, InStr(myTag, ", Ht:"), InStr(myTag, ", Wth:") - InStr(myTag, ", Ht:")))
Dim getW As String = getNum(Mid(myTag, InStr(myTag, ", Wth:")))
lst.Add(getX)
lst.Add(getY)
lst.Add(getH)
lst.Add(getW)
Return lst
End Function
Function getNum(ByVal txt As String)
Dim rtn As String = vbNullString
Dim coln As MatchCollection = Regex.Matches(txt, "\d+")
For Each mtch As Match In coln
rtn = rtn & mtch.ToString
Next
Return Convert.ToInt32(rtn)
End Function
Private Sub PictureBox1_SizeChanged(sender As Object, e As EventArgs) Handles PictureBox1.SizeChanged
Dim lst As New List(Of Int32)
If PictureBox1.Tag <> "" Then
lst = returnPercent(PictureBox1.Tag)
Rct.X = lst(0) * PictureBox1.Width / 100
Rct.Y = lst(1) * PictureBox1.Height / 100
Rct.Height = lst(2) * PictureBox1.Height / 100
Rct.Width = lst(3) * PictureBox1.Width / 100
PictureBox1.Refresh()
End If
End Sub
I have some code that might help you:
' Rectangle to draw
Private Rct As New Rectangle(0, 0, 0, 0)
Private offsetX As Integer = 0
Private offsetY As Integer = 0
Sub Main() Handles MyBase.Load
' Some image to use
MiniPictureBox.Image = My.Resources.P6130003
MainPictureBox.Image = My.Resources.P6130003
End Sub
Private Sub MiniPictureBox_MouseDown(sender As Object, e As MouseEventArgs) Handles MiniPictureBox.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
If Not Rct.Contains(e.Location) Then
' New rectangle
Rct.Location = New Point(e.X, e.Y)
Else
' Moving a rectangle
offsetX = Rct.X - e.X
offsetY = Rct.Y - e.Y
End If
ElseIf e.Button = Windows.Forms.MouseButtons.Right Then
' Clears the screen of a rectangle
Rct = New Rectangle(0, 0, 0, 0)
MiniPictureBox.Invalidate()
End If
End Sub
Private Sub MiniPictureBox_MouseMove(sender As Object, e As MouseEventArgs) Handles MiniPictureBox.MouseMove
' Event handler to update the picture of the rectangle
If e.Button = Windows.Forms.MouseButtons.Left Then
If Rct.Contains(e.Location) Then
' Move the box
Rct.X = e.X + offsetX
Rct.Y = e.Y + offsetY
MainPictureBox.Invalidate()
Else
' Update the size of the box
Rct.Width = e.X - Rct.X
Rct.Height = e.Y - Rct.Y
End If
MiniPictureBox.Invalidate()
End If
End Sub
Private Sub MiniPictureBox_MouseUp(sender As Object, e As MouseEventArgs) Handles MiniPictureBox.MouseUp
' Event handler to call the paint event for runtime display
MiniPictureBox.Invalidate()
MainPictureBox.Invalidate()
End Sub
Private Sub MiniPictureBox_Paint(sender As Object, e As PaintEventArgs) Handles MiniPictureBox.Paint
Dim myPen As Pen = New Pen(Brushes.Red, 2)
e.Graphics.DrawRectangle(myPen, Rct)
End Sub
Private Sub MainPictureBox_Paint(sender As Object, e As PaintEventArgs) Handles MainPictureBox.Paint
If Rct.Width > 0 Then
Dim biggerRec As Rectangle = CalculateRectangle(MainPictureBox)
Dim myPen As Pen = New Pen(Brushes.Red, 2)
e.Graphics.DrawRectangle(myPen, biggerRec)
End If
End Sub
Private Function CalculateRectangle(currentPicture As PictureBox) As Rectangle
Try
Dim newWidth As Integer = (Rct.Width / MiniPictureBox.Width) * currentPicture.Image.Width
Dim newHeight As Integer = (Rct.Height / MiniPictureBox.Height) * currentPicture.Image.Height
Dim newX As Integer = (Rct.X / MiniPictureBox.Width) * currentPicture.Image.Width
Dim newY As Integer = (Rct.Y / MiniPictureBox.Height) * currentPicture.Image.Height
Return New Rectangle(newX, newY, newWidth, newHeight)
Catch ex As Exception
MessageBox.Show(ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace)
End Try
End Function
This code will allow you to create, move, and clear a rectangle. One point of caution is in the calculations for changing the size of the rectangle, you have to ensure exception handling is properly inserted for any arithmetic exceptions.

How to crop an image in vb.net?

The image can be anything. It can be jpg, png, anything.
Load it.
Crop it. Say removing first 100 pixels from the left.
Save to the same file
Use Graphics.DrawImage Method (Image, RectangleF, RectangleF, GraphicsUnit) method.
Dim fileName = "C:\file.jpg"
Dim CropRect As New Rectangle(100, 0, 100, 100)
Dim OriginalImage = Image.FromFile(fileName)
Dim CropImage = New Bitmap(CropRect.Width, CropRect.Height)
Using grp = Graphics.FromImage(CropImage)
grp.DrawImage(OriginalImage, New Rectangle(0, 0, CropRect.Width, CropRect.Height), CropRect, GraphicsUnit.Pixel)
OriginalImage.Dispose()
CropImage.Save(fileName)
End Using
Ref: Graphics.DrawImage and Image Cropping with Image Resizing Using VB.NET
private void btnCropImage_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.ShowDialog();
//check your filename or set constraint on fileopen dialog
//to open image files
string str = dlg.FileName;
//Load Image File to Image Class Object to make crop operation
Image img = System.Drawing.Bitmap.FromFile(str);
// Create rectangle for source image, what ever it's size.
GraphicsUnit units = GraphicsUnit.Pixel;
RectangleF srcRect = img.GetBounds(ref units);
// Create rectangle for displaying image - leaving 100 pixels from left saving image size.
RectangleF destRect = new RectangleF(100.0F, 0.0F, srcRect.Width - 100, srcRect.Height);
// Bitmap class object to which saves croped image
Bitmap bmp = new Bitmap((int)srcRect.Width - 100, (int)srcRect.Height);
// Draw image to screen.
Graphics grp = Graphics.FromImage(bmp);
grp.DrawImage(img, destRect, srcRect, units);
//save image to disk
bmp.Save("e:\\img.jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);
//Clear memory for Unused Source Image
img.Dispose();
}
Hope this help you..
Region "Image Cropping"
Dim cropX As Integer
Dim cropY As Integer
Dim cropWidth As Integer
Dim cropHeight As Integer
Dim oCropX As Integer
Dim oCropY As Integer
Dim cropBitmap As Bitmap
Public cropPen As Pen
Public cropPenSize As Integer = 1 '2
Public cropDashStyle As Drawing2D.DashStyle = Drawing2D.DashStyle.Solid
Public cropPenColor As Color = Color.Yellow
Private Sub RotateBtn_Click(sender As System.Object, e As EventArgs) Handles RotateBtn.Click
' RotateImage(PreviewPictureBox.Image, offset:=, angle:=90)
crobPictureBox.Image.RotateFlip(RotateFlipType.Rotate270FlipNone)
'PreviewPictureBox.Image.RotateFlip(RotateFlipType.Rotate270FlipNone)
'(45, PreviewPictureBox.Image)
End Sub
Private Sub crobPictureBox_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles crobPictureBox.MouseDown
Try
If e.Button = Windows.Forms.MouseButtons.Left Then
cropX = e.X
cropY = e.Y
cropPen = New Pen(cropPenColor, cropPenSize)
cropPen.DashStyle = DashStyle.DashDotDot
Cursor = Cursors.Cross
End If
crobPictureBox.Refresh()
Catch exc As Exception
End Try
End Sub
Dim tmppoint As Point
Private Sub crobPictureBox_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles crobPictureBox.MouseMove
Try
If crobPictureBox.Image Is Nothing Then Exit Sub
If e.Button = Windows.Forms.MouseButtons.Left Then
crobPictureBox.Refresh()
cropWidth = e.X - cropX
cropHeight = e.Y - cropY
crobPictureBox.CreateGraphics.DrawRectangle(cropPen, cropX, cropY, cropWidth, cropHeight)
End If
' GC.Collect()
Catch exc As Exception
If Err.Number = 5 Then Exit Sub
End Try
End Sub
Private Sub crobPictureBox_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles crobPictureBox.MouseUp
Try
Cursor = Cursors.Default
Try
If cropWidth < 1 Then
Exit Sub
End If
Dim rect As Rectangle = New Rectangle(cropX, cropY, cropWidth, cropHeight)
Dim bit As Bitmap = New Bitmap(crobPictureBox.Image, crobPictureBox.Width, crobPictureBox.Height)
cropBitmap = New Bitmap(cropWidth, cropHeight)
Dim g As Graphics = Graphics.FromImage(cropBitmap)
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
g.DrawImage(bit, 0, 0, rect, GraphicsUnit.Pixel)
' g.DrawImage(bit, 0, 0, rect,GraphicsUnit.Pixel)
PreviewPictureBox.Image = cropBitmap
Catch exc As Exception
End Try
Catch exc As Exception
End Try
End Sub

Scaling image for printing

I'm using the following code to print an image from a PictureBox.
All works great except for scaling images down if they are bigger than the print page.
Is there a method I'm missing to do this?
Screenshot, large image outside of the paper bounds:
http://a.yfrog.com/img46/63/problemsh.png http://a.yfrog.com/img46/63/problemsh.png
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
AddHandler PrintDocument1.PrintPage, AddressOf OnPrintPage
With PageSetupDialog1
.Document = PrintDocument1
.PageSettings = PrintDocument1.DefaultPageSettings
If PictureEdit1.Image.Height >= PictureEdit1.Image.Width Then
PageSetupDialog1.PageSettings.Landscape = False
Else
PageSetupDialog1.PageSettings.Landscape = True
End If
End With
PrintDialog1.UseEXDialog = True
PrintDialog1.Document = PrintDocument1
If PrintDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
PrintPreviewDialog1.Document = PrintDocument1
If PrintPreviewDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
PrintDocument1.DefaultPageSettings = PageSetupDialog1.PageSettings
PrintDocument1.Print()
End If
End If
End Sub
Private Sub OnPrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
Dim img As Image = PictureEdit1.Image
Dim sz As New SizeF(100 * img.Width / img.HorizontalResolution, 100 * img.Height / img.VerticalResolution)
Dim p As New PointF((e.PageBounds.Width - sz.Width) / 2, (e.PageBounds.Height - sz.Height) / 2)
e.Graphics.DrawImage(img, p)
End Sub
Replace:
Dim sz As New SizeF(100 * img.Width / img.HorizontalResolution, 100 * img.Height / img.VerticalResolution)
With something like this to fit the image in the page:
dim ScaleFac as integer = 100
While (ScaleFac * img.Width / img.HorizontalResolution > e.PageBounds.Width or ScaleFac * img.Height / img.VerticalResolution > e.PageBounds.Height) and ScaleFac > 2
ScaleFac -= 1
Wend
Dim sz As New SizeF(ScaleFac * img.Width / img.HorizontalResolution, ScaleFac* img.Height / img.VerticalResolution)
You could use algebra to solve for the proper scalefac, but I don't have time to test it and if you didn't understand what I'd done that would be a lot harder for you to debug. Pretty sure you'll see what I'm trying to do here from the just the code alone! Regards.
Dim img As Image = PictureEdit1.Image
e.Graphics.DrawImage(img, 0, 0,
e.PageBounds.Width, e.PageBounds.Height)
is all that you will need to solve