如何调整PictureBox内的图像大小? [英] How to resize the image inside the PictureBox?
本文介绍了如何调整PictureBox内的图像大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
如何调整PictureBox中的图像大小?
我的意思是不调整PictureBox的大小,而是调整其中的图片大小。
How to resize the image inside the PictureBox?
I mean not to resize the PictureBox but to resize the picture in it.
推荐答案
这是我在过去几年中拼凑过来的各种来源,经过大量修改,你可以用来做图像尺寸缩放(使用stretchblit),jpeg压缩调整,采取桌面截图等。您将要使用:
Here''s a class that I cobbled together over the last few years from various sources, and heavily modified, that you can use to do image size scaling (using stretchblit), jpeg compression tweaking, take desktop screenshots, ect. You will want to use the:
Public Function ResizeImage(ByVal sourceBitmap As Bitmap, ByVal newWidth As Integer, ByVal newHeight As Integer, Optional ByVal bpp As Short = 24) As Image
方法。
代码:
method.
code:
Option Strict On
Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.IO
Public Class clsGDI_Graphics
' vbPaletteMode(s):
' vbPaletteModeHalfTone = 0 - (Default) Use the Halftone palette.
' vbPaletteModeUseZOrder = 1 - Use the palette from the topmost control that has a palette.
' vbPaletteModeCustom = 2 - Use the palette specified in the "Palette" property.
' vbPaletteModeContainer = 3 - Use the container's palette for containers that support ambient Palette property. Applies to UserControls only.
' vbPaletteModeNone = 4 - Do not use any palette. Applies to UserControls only.
' vbPaletteModeObject = 5 - Use the ActiveX designers palette. (Applies only to ActiveX designers which contain a palette.)
Const STRETCHMODE As Integer = 4 ' vbPaletteModeNone
Shared BI_RGB As UInteger = 0
Shared DIB_RGB_COLORS As UInteger = 0
' Creates an Image object containing a screen shot of the entire desktop
Public Function CaptureScreen() As Image
Return CaptureWindow(User32.GetDesktopWindow())
End Function 'CaptureScreen
Public Function CaptureScreenAndResize(ByVal newWidth As Integer, ByVal newHeight As Integer) As Image
Return CaptureWindowAndResize(User32.GetDesktopWindow(), newWidth, newHeight)
End Function
Public Function CaptureWindowAndResize(ByVal handle As IntPtr, ByVal newWidth As Integer, ByVal newHeight As Integer, _
Optional mode As Int32 = GDI32.StretchBltMode.STRETCH_DELETESCANS) As Image
' get te hDC of the target window
Dim hdcSrc As IntPtr = User32.GetWindowDC(handle)
' get the size
Dim windowRect As New User32.RECT()
User32.GetWindowRect(handle, windowRect)
Dim width As Integer = windowRect.right - windowRect.left
Dim height As Integer = windowRect.bottom - windowRect.top
' create a device context we can copy to
Dim hdcDest As IntPtr = GDI32.CreateCompatibleDC(hdcSrc)
' create a bitmap we can copy it to,
' using GetDeviceCaps to get the width/height
Dim hBitmap As IntPtr = GDI32.CreateCompatibleBitmap(hdcSrc, width, height)
' select the bitmap object
Dim hOld As IntPtr = GDI32.SelectObject(hdcDest, hBitmap)
' SetStretchBltMode to handle image artifacts
GDI32.SetStretchBltMode(hdcDest, gdi32.StretchBltMode.STRETCH_HALFTONE)
' StretchBlt over
GDI32.StretchBlt(hdcDest, 0, 0, newWidth, newHeight, hdcSrc, 0, 0, width, height, TernaryRasterOperations.SRCCOPY)
' restore selection
GDI32.SelectObject(hdcDest, hOld)
' clean up
GDI32.DeleteDC(hdcDest)
User32.ReleaseDC(handle, hdcSrc)
' get a .NET image object for it
Dim img As Image = Image.FromHbitmap(hBitmap)
' free up the Bitmap object
GDI32.DeleteObject(hBitmap)
Return img
End Function
' Creates an Image object containing a screen shot of a specific window
Public Function CaptureWindow(ByVal handle As IntPtr) As Image
' get te hDC of the target window
Dim hdcSrc As IntPtr = User32.GetWindowDC(handle)
' get the size
Dim windowRect As New User32.RECT()
User32.GetWindowRect(handle, windowRect)
Dim width As Integer = windowRect.right - windowRect.left
Dim height As Integer = windowRect.bottom - windowRect.top
' create a device context we can copy to
Dim hdcDest As IntPtr = GDI32.CreateCompatibleDC(hdcSrc)
' create a bitmap we can copy it to,
' using GetDeviceCaps to get the width/height
Dim hBitmap As IntPtr = GDI32.CreateCompatibleBitmap(hdcSrc, width, height)
' select the bitmap object
Dim hOld As IntPtr = GDI32.SelectObject(hdcDest, hBitmap)
' bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY)
' restore selection
GDI32.SelectObject(hdcDest, hOld)
' clean up
GDI32.DeleteDC(hdcDest)
User32.ReleaseDC(handle, hdcSrc)
' get a .NET image object for it
Dim img As Image = Image.FromHbitmap(hBitmap)
' free up the Bitmap object
GDI32.DeleteObject(hBitmap)
Return img
End Function 'CaptureWindow
' For CaptureWindowFromDevice
Private Declare Function CreateCompatibleDC Lib "GDI32" (ByVal hDC As Integer) As Integer
Private Declare Function CreateCompatibleBitmap Lib "GDI32" (ByVal hDC As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer) As Integer
Private Declare Function GetDeviceCaps Lib "gdi32" Alias "GetDeviceCaps" (ByVal hdc As Integer, ByVal nIndex As Integer) As Integer
Private Declare Function SelectObject Lib "GDI32" (ByVal hDC As Integer, ByVal hObject As Integer) As Integer
Private Declare Function BitBlt Lib "GDI32" (ByVal srchDC As Integer, ByVal srcX As Integer, ByVal srcY As Integer, ByVal srcW As Integer, ByVal srcH As Integer, ByVal desthDC As Integer, ByVal destX As Integer, ByVal destY As Integer, ByVal op As Integer) As Integer
Private Declare Function DeleteDC Lib "GDI32" (ByVal hDC As Integer) As Integer
Private Declare Function DeleteObject Lib "GDI32" (ByVal hObj As Integer) As Integer
Const SRCCOPY As Integer = &HCC0020
' Creates an Image object containing a screen shot of a specific window
Public Function CaptureWindowFromPrimaryDevice() As Image
Dim hSDC, hMDC As Integer
Dim hBMP, hBMPOld As Integer
Dim FW, FH As Integer
Dim r As Integer
hSDC = GDI32.CreateDC(enumDisplayDevicesForPrimary, "", "", "")
hMDC = CreateCompatibleDC(hSDC)
FW = GetDeviceCaps(hSDC, 8)
FH = GetDeviceCaps(hSDC, 10)
hBMP = CreateCompatibleBitmap(hSDC, FW, FH)
hBMPOld = SelectObject(hMDC, hBMP)
r = BitBlt(hMDC, 0, 0, FW, FH, hSDC, 0, 0, 13369376)
hBMP = SelectObject(hMDC, hBMPOld)
r = DeleteDC(hSDC)
r = DeleteDC(hMDC)
CaptureWindowFromPrimaryDevice = Image.FromHbitmap(New IntPtr(hBMP))
DeleteObject(hBMP)
End Function 'CaptureWindow
' Captures a screen shot of a specific window, and saves it to a file
Public Sub CaptureWindowToFile(ByVal handle As IntPtr, ByVal filename As String, ByVal format As ImageFormat)
Dim img As Image = CaptureWindow(handle)
img.Save(filename, format)
End Sub 'CaptureWindowToFile
' Captures a screen shot of the entire desktop, and saves it to a file
Public Sub CaptureScreenToFile(ByVal filename As String, ByVal format As ImageFormat)
Dim img As Image = CaptureScreen()
img.Save(filename, format)
End Sub 'CaptureScreenToFile
Public Function ByteArrayToImage(ByVal ByteArray() As Byte) As Image
Dim ImageStream As MemoryStream
Try
If ByteArray.GetUpperBound(0) > 0 Then
ImageStream = New MemoryStream(ByteArray)
ByteArrayToImage = Image.FromStream(ImageStream)
Else
ByteArrayToImage = Nothing
End If
Catch ex As Exception
ByteArrayToImage = Nothing
End Try
End Function
Public Function ImageToByteArray(ByRef NewImage As Image, ByRef ByteArray() As Byte, Optional ByVal errMsg As String = "") As Boolean
Dim ImageStream As MemoryStream
ImageToByteArray = True
Try
ReDim ByteArray(0)
If NewImage IsNot Nothing Then
ImageStream = New MemoryStream
NewImage.Save(ImageStream, ImageFormat.Jpeg)
ByteArray = ImageStream.GetBuffer
End If
Catch ex As Exception
ImageToByteArray = False
errMsg = ex.Message
End Try
End Function
' .biSizeImage = Abs(.biHeight) * ByteAlignOnWord(.biBitCount, .biWidth)
Private Function ByteAlignOnWord(ByVal BitDepth As Byte, ByVal Width As Long) As Long
' function to align any bit depth on dWord boundaries
ByteAlignOnWord = (((Width * BitDepth) + &H1F&) And Not &H1F&) \ &H8&
End Function
Public Function ResizeImage(ByVal sourceBitmap As Bitmap, ByVal newWidth As Integer, _
ByVal newHeight As Integer, Optional ByVal bpp As Short = 24) As Image
' (1) Convert our Bitmap into a GDI hbitmap (ie. copy unmanaged->managed)
Dim sourceWidth As Integer = sourceBitmap.Width
Dim sourceHeight As Integer = sourceBitmap.Height
Dim hbm As IntPtr = sourceBitmap.GetHbitmap()
' (2) Create the canvas bitmap.
' "BITMAPINFO" is an interop-struct which we define below.
Dim bmi As New BITMAPINFO()
bmi.biSize = 40
bmi.biWidth = newWidth
bmi.biHeight = newHeight
bmi.biPlanes = 1
bmi.biBitCount = bpp
bmi.biCompression = BI_RGB
bmi.biSizeImage = CUInt(Math.Abs(bmi.biHeight) * ByteAlignOnWord(CByte(bmi.biBitCount), bmi.biWidth))
bmi.biXPelsPerMeter = 1000000
bmi.biYPelsPerMeter = 1000000
' Now create the DIBSection bitmap "hbm0"
Dim bits0 As IntPtr ' It returns a pointer to the raw bits that make up the bitmap.
Dim hbm0 As IntPtr = GDI32.CreateDIBSection(IntPtr.Zero, bmi, DIB_RGB_COLORS, bits0, IntPtr.Zero, 0)
'
' (3): use GDI's SetStretchBltMode function to copy from original hbitmap into altered bitmap
' Obtain the DC for the screen
Dim sdc As IntPtr = GDI32.GetDC(IntPtr.Zero)
' Next, create a DC for the original hbitmap
Dim hdc As IntPtr = GDI32.CreateCompatibleDC(sdc)
GDI32.SelectObject(hdc, hbm)
' and create a DC for the altered hbitmap
Dim hdc0 As IntPtr = GDI32.CreateCompatibleDC(sdc)
GDI32.SelectObject(hdc0, hbm0)
' Now we do our StretchBlt:
GDI32.SetStretchBltMode(hdc0, GDI32.StretchBltMode.STRETCH_ORSCANS)
GDI32.StretchBlt(hdc0, 0, 0, newWidth, newHeight, hdc, 0, 0, sourceWidth, sourceHeight, TernaryRasterOperations.SRCCOPY)
' Get the results
Dim finishedImage As System.Drawing.Image = System.Drawing.Image.FromHbitmap(hbm0)
' Some cleanup.
GDI32.DeleteDC(hdc)
GDI32.DeleteDC(hdc0)
User32.ReleaseDC(IntPtr.Zero, sdc)
GDI32.DeleteObject(hbm)
GDI32.DeleteObject(hbm0)
Return finishedImage
End Function
<flags()> _
Enum DisplayDeviceStateFlags As Integer
''' <summary>The device is part of the desktop.</summary>
AttachedToDesktop = &H1
MultiDriver = &H2
''' <summary>The device is part of the desktop.</summary>
PrimaryDevice = &H4
''' <summary>Represents a pseudo device used to mirror application drawing for remoting or other purposes.</summary>
MirroringDriver = &H8
''' <summary>The device is VGA compatible.</summary>
VGACompatible = &H16
''' <summary>The device is removable; it cannot be the primary display.</summary>
Removable = &H20
''' <summary>The device has more display modes than its output devices support.</summary>
ModesPruned = &H8000000
Remote = &H4000000
Disconnect = &H2000000
End Enum
<structlayout(layoutkind.sequential,> _
Public Structure DISPLAY_DEVICE
<marshalas(unmanagedtype.u4)> _
Public cb As Integer
<marshalas(unmanagedtype.byvaltstr,> _
Public DeviceName As String
<marshalas(unmanagedtype.byvaltstr,> _
Public DeviceString As String
<marshalas(unmanagedtype.u4)> _
Public StateFlags As DisplayDeviceStateFlags
<marshalas(unmanagedtype.byvaltstr,> _
Public DeviceID As String
<marshalas(unmanagedtype.byvaltstr,> _
Public DeviceKey As String
End Structure
<dllimport("user32.dll")> _
Private Shared Function EnumDisplayDevices(ByVal lpDevice As String, ByVal iDevNum As UInteger, ByRef lpDisplayDevice As DISPLAY_DEVICE, ByVal dwFlags As UInteger) As Boolean
End Function
Public Function enumDisplayDevicesForPrimary() As String
Dim device As DISPLAY_DEVICE = New DISPLAY_DEVICE()
device.cb = Marshal.SizeOf(device)
enumDisplayDevicesForPrimary = ""
Try
Dim id As UInteger = 0
While enumDisplayDevices(Nothing, id, device, 0)
If device.StateFlags.ToString.Contains("PrimaryDevice") Then
Return device.DeviceName
End If
device.cb = Marshal.SizeOf(device)
' Run EnumDisplayDevices a second time to get access to connected monitor
enumDisplayDevices(device.DeviceName, 0, device, 0)
device.cb = Marshal.SizeOf(device)
id = CUInt(id + 1)
End While
Catch ex As Exception
Console.WriteLine([String].Format("{0}", ex.ToString()))
End Try
End Function
Private Class JpegTools
Private codecs As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
Private quality As Long
Public ici As ImageCodecInfo = Nothing
Public ep As New EncoderParameters()
Public compressionRatio As Long
Public Sub new(ByVal _compressionRatio As Long, Optional ByRef errMsg As String = "")
compressionRatio = _compressionRatio
If compressionRatio < 0 then compressionRatio = 0
If compressionRatio > 100 then compressionRatio = 100
quality = (100 - compressionRatio)
Try
For Each codec As ImageCodecInfo In codecs
If codec.MimeType = "image/jpeg" Then
ici = codec
End If
Next
ep.Param(0) = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality)
Catch ex As Exception
errMsg = ex.Message
End Try
End Sub
End Class
Private JpgTools As JpegTools
' Save an Image() to a jpeg file and specify the compression % (Valid values for compressionRatio are 0 - 100)
Public Function SaveImgToFile(ByRef img As Image, ByVal fullPathWithFileName As String, ByVal compressionRatio As Long, _
Optional ByRef errMsg As String = "") As Boolean
If JpgTools Is Nothing Then JpgTools = New JpegTools(compressionRatio, errMsg)
If JpgTools.compressionRatio <> compressionRatio then JpgTools = New JpegTools(compressionRatio, errMsg)
If errMsg <> "" then Return False
Try
img.Save(fullPathWithFileName, JpgTools.ici, JpgTools.ep)
Catch ex As Exception
errMsg = ex.Message
Return False
End Try
Return True
End Function
' Helper class containing Gdi32 API functions
Public Class GDI32
Public Shared SRCCOPY As Integer = &HCC0020
' BitBlt dwRop parameter
<dllimport("user32.dll")> _
Public Shared Function GetDC(ByVal hwnd As IntPtr) As IntPtr
End Function
<system.runtime.interopservices.dllimport("gdi32.dll")> _
Public Shared Function CreateDIBSection(ByVal hdc As IntPtr, _
ByRef bmi As BITMAPINFO, ByVal Usage As UInteger, ByVal bits As IntPtr, _
ByVal hSection As IntPtr, ByVal dwOffset As UInteger) As IntPtr
End Function
<dllimport("gdi32.dll")> _
Public Shared Function BitBlt(ByVal hObject As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, _
ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hObjectSource As IntPtr, _
ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As Integer) As Boolean
End Function
<dllimport("gdi32.dll")> _
Public Shared Function StretchBlt(ByVal hdcDest As IntPtr, _
ByVal nXOriginDest As Integer, _
ByVal nYOriginDest As Integer, _
ByVal nWidthDest As Integer, _
ByVal nHeightDest As Integer, _
ByVal hdcSrc As IntPtr, _
ByVal nXOriginSrc As Integer, _
ByVal nYOriginSrc As Integer, _
ByVal nWidthSrc As Integer, _
ByVal nHeightSrc As Integer, _
ByVal dwRop As TernaryRasterOperations) As Boolean
End Function
Public Enum StretchBltMode As Integer
STRETCH_ANDSCANS = 1
STRETCH_ORSCANS = 2
STRETCH_DELETESCANS = 3
STRETCH_HALFTONE = 4
End Enum
<dllimport("gdi32.dll")> _
Public Shared Function SetStretchBltMode(hdc As IntPtr, iStretchMode As StretchBltMode) As Boolean
End Function
<dllimport("gdi32.dll")> _
Public Shared Function CreateBitmap(ByVal nWidth As Integer, ByVal nHeight As Integer, _
ByVal cPlanes As UInteger, ByVal cBitsPerPel As UInteger, _
ByVal lpvBits As IntPtr) As IntPtr
End Function
<dllimport("gdi32.dll")> _
Public Shared Function CreateDC(ByVal lpDriverName As String, ByVal lpDeviceName As String, _
ByVal lpOutput As String, ByVal lpInitData As String) As Integer
End Function
<dllimport("gdi32.dll")> _
Public Shared Function GetDeviceCaps(ByVal hdc As Integer, ByVal nIndex As Integer) As Integer
End Function
<dllimport("gdi32.dll")> Public Shared Function CreateCompatibleBitmap(ByVal hDC As IntPtr, _
ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr
End Function
<dllimport("gdi32.dll")> Public Shared _
Function CreateCompatibleDC(ByVal hDC As IntPtr) As IntPtr
End Function
<dllimport("gdi32.dll")> Public Shared _
Function DeleteDC(ByVal hDC As IntPtr) As Boolean
End Function
<dllimport("gdi32.dll")> Public Shared _
Function DeleteObject(ByVal hObject As IntPtr) As Boolean
End Function
<dllimport("gdi32.dll")> Public Shared _
Function SelectObject(ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
End Function
End Class 'GDI32
' Helper class containing User32 API functions
Private Class User32
<structlayout(layoutkind.sequential)> _
Public Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
End Structure 'RECT
<dllimport("user32.dll",> _
Public Shared Function OpenInputDesktop(ByVal dwFlags As UInteger, _
ByVal fInherit As Boolean, _
ByVal dwDesiredAccess As UInteger) As IntPtr
End Function
<dllimport("user32.dll")> Public Shared _
Function GetDesktopWindow() As IntPtr
End Function
<dllimport("user32.dll")> Public Shared _
Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
End Function
<dllimport("user32.dll")> Public Shared _
Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As IntPtr
End Function
<dllimport("user32.dll")> Public Shared _
Function GetWindowRect(ByVal hWnd As IntPtr, ByRef rect As RECT) As IntPtr
End Function
<dllimport("user32.dll")> _
Public Shared Function InvalidateRect(ByVal hwnd As IntPtr, ByVal rect As IntPtr, _
ByVal bErase As Integer) As Integer
End Function
End Class 'User32
''' <summary>
''' Specifies a raster-operation code. These codes define how the color data for the
''' source rectangle is to be combined with the color data for the destination
''' rectangle to achieve the final color.
''' </summary>
Enum TernaryRasterOperations As UInteger
''' <summary>dest = source</summary>
SRCCOPY = &HCC0020
''' <summary>dest = source OR dest</summary>
SRCPAINT = &HEE0086
''' <summary>dest = source AND dest</summary>
SRCAND = &H8800C6
''' <summary>dest = source XOR dest</summary>
SRCINVERT = &H660046
''' <summary>dest = source AND (NOT dest)</summary>
SRCERASE = &H440328
''' <summary>dest = (NOT source)</summary>
NOTSRCCOPY = &H330008
''' <summary>dest = (NOT src) AND (NOT dest)</summary>
NOTSRCERASE = &H1100A6
''' <summary>dest = (source AND pattern)</summary>
MERGECOPY = &HC000CA
''' <summary>dest = (NOT source) OR dest</summary>
MERGEPAINT = &HBB0226
''' <summary>dest = pattern</summary>
PATCOPY = &HF00021
''' <summary>dest = DPSnoo</summary>
PATPAINT = &HFB0A09
''' <summary>dest = pattern XOR dest</summary>
PATINVERT = &H5A0049
''' <summary>dest = (NOT dest)</summary>
DSTINVERT = &H550009
''' <summary>dest = BLACK</summary>
BLACKNESS = &H42
''' <summary>dest = WHITE</summary>
WHITENESS = &HFF0062
''' <summary>
''' Capture window as seen on screen. This includes layered windows
''' such as WPF windows with AllowsTransparency="true"
''' </summary>
CAPTUREBLT = &H40000000
End Enum
<system.runtime.interopservices.structlayout(system.runtime.interopservices.layoutkind.sequential)> _
Public Structure BITMAPINFO
Public biSize As UInteger
Public biWidth As Integer, biHeight As Integer
Public biPlanes As Short, biBitCount As Short
Public biCompression As UInteger, biSizeImage As UInteger
Public biXPelsPerMeter As Integer, biYPelsPerMeter As Integer
Public biClrUsed As UInteger, biClrImportant As UInteger
<system.runtime.interopservices.marshalas(system.runtime.interopservices.unmanagedtype.byvalarray,> _
Public cols As UInteger()
End Structure
Private Shared Function MAKERGB(ByVal r As Integer, ByVal g As Integer, ByVal b As Integer) As UInteger
Return CUInt(b And 255) Or CUInt((r And 255) << 8) Or CUInt((g And 255) << 16)
End Function
End Class 'ScreenCapture
hope this helps.
- Pete
hope this helps.
- Pete
这篇关于如何调整PictureBox内的图像大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文