當前位置:編程學習大全網 - 源碼下載 - VB 修改圖片的尺寸並保存,比如現有圖片256*128,我要修改成15*15的尺寸,要源碼!

VB 修改圖片的尺寸並保存,比如現有圖片256*128,我要修改成15*15的尺寸,要源碼!

首先,聲明以下核心代碼部分完全照抄,由CSDN上laviewpbt提供,我在之前壹篇VB常見問題裏給出過鏈接。當時提到VB的效率問題,我舉

出圖片縮放的例子,用VB寫的圖片縮放,效率居然很高,以此證明算法的重要性。laviewpbt又是受到了CSDN上zyl910,本名好像叫周嶽靈的

激發,結果做出的程序效率更加驚人。有興趣的可以看看我這篇文章裏給出的論壇鏈接。

所以,我這裏用的解決方法就是從他們這裏得來。不過這些高人們關註的是效率,程序裏面有很大篇幅是不同算法比較,已經時間測試。而對於更加關心使用的人來說,代碼需要裁剪。我粗略的篩選了下,對模塊內容沒有改動,而只是從主程序裏撥出我們需要的內容。

那麽,就開始吧。

首先,用到三個模塊和壹個類模塊,這部分代碼我們不用重寫了。程序搭建時候添加進去。需要說明的是,如果妳已經有壹個在做的項目,那麽簡單的導入模塊可能是不行的。laviewpbt給我們做了壹個很好的示範,他的API聲明都是在壹個模塊裏面的,那麽妳的項目最好也這樣,然後,把他的API聲明貼在後面,運行程序時候如果有重復,會自動找到,然後妳就停掉他,註釋掉或者刪除。這幾個模塊的內容我最後貼出,這裏到現在也不能上傳附件。

那麽,我們重點要介紹怎麽用。

Private DIBData As CImagePrivate DIBWork As CImage

首先要聲明兩個類變量。這個是我們自定義的類。在模塊裏。

接著兩段代碼,壹個加載圖片,壹個改變圖片大小。

我們要打開圖片,初始化上面這兩個量,初始化過程寫在 form_load裏面

Set DIBData = New CImage

Set DIBWork = New CImage

scaNum = 1 '這個是比例

scaWidth = Me.Width '這個是窗體寬度的初始參照值

Picture1.Picture = LoadPicture(App.Path & "\手球場地小圖.jpg")

Dim DIBTemp As New CImage

If DIBTemp.LoadPictureFromFile(App.Path & "\手球場地小圖.jpg") = True Then

Set DIBData = DIBTemp

DIBWork.DisposeResource

Picture1.Width = DIBData.Width

Picture1.Height = DIBData.Height

DIBData.Render Picture1.Hdc

Picture1.Refresh

Else

MsgBox "錯誤的圖像文件", vbCritical

End If

Set DIBTemp = Nothing

當窗體大小變化的時候,我們再寫壹段代碼改變圖片大小已經PictureBox大小任務就完成了。

需要說明的是,以下調用的代碼,對尺寸的計量單位是pixel,而VB窗體默認的計量單位是Tiwp,顯示器上壹個pixel裏面可以有很多twip,如果妳做出來的程序,圖像順暢顯示了,但是就是很小,那麽,恭喜妳,妳成功了,只是需要將尺寸轉換成vb裏面的tiwp,

乘以 Screen.TwipsPerPixelX

這段代碼如下:

Dim W As Long, H As Long

W = DIBData.Width * scaNum

H = DIBData.Height * scaNum

If W < 1 Then W = 1 If H < 1 Then H = 1

Dim DIBTemp As New CImage

Dim t As Currency

Me.MousePointer = vbHourglass

t = Utility.GetCurrentTime

Set DIBTemp = Resample(DIBData, W, H, 2) '這裏固定選擇壹個算法,雙線性內插值

' t = GetCurrentTime - t

Me.MousePointer = vbDefault

' Me.Caption = " 處理時間:" & Format(t / 1000, "##,###,##0.000") & "秒"

Set DIBWork = DIBTemp

Set DIBTemp = Nothing

PicData.Width = DIBWork.Width * Screen.TwipsPerPixelX

PicData.Height = DIBWork.Height * Screen.TwipsPerPixelX

DIBWork.Render PicData.Hdc

' SolNum

PicData.Refresh

代碼被我註釋掉壹部分,原代碼中有時間測試內容。

把這段代碼獨立成壹個Sub,然後在form_reSize裏面調用,當然,調用之前首先要計算變化比例scaNum

下面開貼模塊代碼

模塊壹、ImageResize模塊:

Option Explicit

Public Enum ResizeModeConst

SMC_Nearest = 0 '最鄰近插值

SMC_StretchBlt = 1 'StretchBlt

SMC_BiliNear = 2 '雙線性內插值

End Enum

Public

Function Resample(Img As CImage, NewWidth As Long, NewHeight As Long,

Optional Method As ResizeModeConst = SMC_BiliNear) As CImage

Dim X As Long, Y As Long

Dim XX As Long, YY As Long

Dim OldYY As Long

Dim Width As Long, Height As Long

Dim Sa As SAFEARRAY, SaN As SAFEARRAY

Dim ImageData() As Byte, NewImageData() As Byte

Dim Stride As Long, NewStride As Long

Dim Offset As Long

Dim Speed As Long, SpeedN As Long

Dim NewImg As New CImage

If NewImg.CreateNewImage(NewWidth, NewHeight) = True Then

With Sa

.Element = 1

.Dimension = 1

.Bounds.Elements = Img.Stride * Img.Height

.Pointer = Img.Pointer

End With

CopyMemory ByVal VarPtrArray(ImageData()), VarPtr(Sa), 4

With SaN

.Element = 1

.Dimension = 1

.Bounds.Elements = NewImg.Stride * NewImg.Height

.Pointer = NewImg.Pointer

End With

CopyMemory ByVal VarPtrArray(NewImageData()), VarPtr(SaN), 4

Width = Img.Width: Height = Img.Height

Stride = Img.Stride: NewStride = NewImg.Stride

ReDim LinearRow(NewWidth - 1) As Long

Select Case Method

Case ResizeModeConst.SMC_Nearest

OldYY = -1

For X = 0 To NewWidth - 1

LinearRow(X) = (X * Width \ NewWidth) * 3

Next

For Y = 0 To NewHeight - 1

SpeedN = Y * NewStride

YY = Y * Height \ NewHeight

Offset = YY * Stride

If YY = OldYY Then

CopyMemory NewImageData(SpeedN), NewImageData(SpeedN - NewStride), NewStride

Else

OldYY = YY

For X = 0 To NewWidth - 1

Speed = Offset + LinearRow(X)

NewImageData(SpeedN) = ImageData(Speed)

NewImageData(SpeedN + 1) = ImageData(Speed + 1)

NewImageData(SpeedN + 2) = ImageData(Speed + 2)

SpeedN = SpeedN + 3

Next

End If

Next

Case ResizeModeConst.SMC_StretchBlt

Img.Render NewImg.Hdc, 0, 0, NewImg.Width, NewImg.Height, 0, 0, Img.Width, Img.Height

Case ResizeModeConst.SMC_BiliNear

Dim PartXX As Long, PartYY As Long

Dim InvertXX As Long, InvertYY As Long

Dim NewX As Long, NewY As Long

Dim SpeedP As Long, ColOffset As Long

Dim Pos As Double

ReDim RowOffset(NewWidth - 1) As Long

ReDim RowPartXX(NewWidth - 1) As Long

For X = 0 To NewWidth - 1

Pos = X * (Width - 1) / NewWidth

RowOffset(X) = Int(Pos) * 3

RowPartXX(X) = (Pos - Int(Pos)) * 2048

Next

For Y = 0 To NewHeight - 1

SpeedN = Y * NewStride

Pos = Y * (Height - 1) / NewHeight

PartYY = (Pos - Int(Pos)) * 2048

InvertYY = 2048 - PartYY

ColOffset = Int(Pos) * Stride

For X = 0 To NewWidth - 1

PartXX = RowPartXX(X)

InvertXX = 2048 - PartXX

Speed = ColOffset + RowOffset(X)

SpeedP = Speed + Stride

NewImageData(SpeedN + 2) = ((ImageData(Speed + 2) * InvertXX +

ImageData(Speed + 5) * PartXX) * InvertYY + (ImageData(SpeedP + 2) *

InvertXX + ImageData(SpeedP + 5) * PartXX) * PartYY) \ 4194304

NewImageData(SpeedN + 1) = ((ImageData(Speed + 1) * InvertXX +

ImageData(Speed + 4) * PartXX) * InvertYY + (ImageData(SpeedP + 1) *

InvertXX + ImageData(SpeedP + 4) * PartXX) * PartYY) \ 4194304

NewImageData(SpeedN) = ((ImageData(Speed) * InvertXX + ImageData(Speed +

3) * PartXX) * InvertYY + (ImageData(SpeedP) * InvertXX +

ImageData(SpeedP + 3) * PartXX) * PartYY) \ 4194304

SpeedN = SpeedN + 3

Next

Next

End Select

CopyMemory ByVal VarPtrArray(ImageData()), 0&, 4

CopyMemory ByVal VarPtrArray(NewImageData()), 0&, 4

End If

Set Resample = NewImg

End Function

模塊2、可以忽略的和時間測試有關部分,內容不多,也貼出

Private SystemFrequency As Currency

Public Function GetCurrentTime() As Currency

If SystemFrequency = 0 Then '未初始化

If QueryPerformanceFrequency(SystemFrequency) = 0 Then

SystemFrequency = ERRORINDEX '無高精度計數器

End If

End If

If SystemFrequency <> ERRORINDEX Then

Dim CurCount As Currency

QueryPerformanceCounter CurCount

GetCurrentTime = CurCount * 1000@ / SystemFrequency

Else

GetCurrentTime = GetTickCount()

End If

End Function

模塊3、API聲明部分,需要妳自己解決沖突問題。

Option Explicit

Public Const ERRORINDEX As Long = -1

Public Const DIB_RGB_COLORS As Long = 0

Public Const BI_RGB As Long = 0 '正常

Public Const STRETCH_ANDSCANS As Long = 1

Public Const STRETCH_DELETESCANS As Long = 3

Public Const STRETCH_HALFTONE As Long = 4

Public Const STRETCH_ORSCANS As Long = 2

Public Type RECT

Left As Long

Top As Long

Right As Long

Bottom As Long

End Type

Public Type POINTAPI

X As Long

Y As Long

End Type

Public Type RGBQUAD

Blue As Byte

Green As Byte

Red As Byte

Alpha As Byte

End Type

Public Type LOGPALETTE

palVersion As Integer

palNumEntries As Integer

palPalEntry(255) As RGBQUAD

End Type

Public Type SAFEARRAYBOUND

Elements As Long

lLbound As Long

End Type

Public Type SAFEARRAY2D

Dimension As Integer

Features As Integer

Element As Long

Locks As Long

Pointer As Long

Bounds(1) As SAFEARRAYBOUND

End Type

Public Type SAFEARRAY

Dimension As Integer

Features As Integer

Element As Long

Locks As Long

Pointer As Long

Bounds As SAFEARRAYBOUND

End Type

Public Type BITMAPINFOHEADER

Size As Long

Width As Long

Height As Long

Planes As Integer

BitCount As Integer

Compression As Long

SizeImage As Long

XPelsPerMeter As Long

YPelsPerMeter As Long

ClrUsed As Long

ClrImportant As Long

End Type

Public Type BITMAPINFO

Header As BITMAPINFOHEADER

Palette(255) As RGBQUAD

End Type

Public Type Bitmap

Type As Long

Width As Long

Height As Long

WidthBytes As Long

Planes As Integer

BitsPixel As Integer

Bits As Long

End Type

'

'內存操作相關API

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDst As Any, lpSrc As Any, ByVal ByteLength As Long)

Public Declare Sub ZeroMemory Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, ByVal numBytes As Long)

Public

Declare Sub FillMemory Lib "kernel32.dll" Alias "RtlFillMemory" (ByRef

Destination As Any, ByVal Length As Long, ByVal Fill As Byte)

'VB本體API

Public

Declare Function OleLoadPicture Lib "olepro32" (pStream As Any, ByVal

lSize As Long, ByVal fRunmode As Long, riid As Any, ppvObj As Any) As

Long

Public Declare Function SafeArrayGetDim Lib "oleaut32.dll" (ByRef saArray() As Any) As Long

Public Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (ByRef Ptr() As Any) As Long

'GDI系統API函數

Public Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long

Public Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal Hdc As Long) As Long

Public

Declare Function CreateDIBSection Lib "gdi32.dll" (ByVal Hdc As Long,

ByRef pBitmapInfo As Any, ByVal un As Long, ByRef Pointer As Long, ByVal

Handle As Long, ByVal Dw As Long) As Long

Public Declare Function DeleteDC Lib "gdi32.dll" (ByVal Hdc As Long) As Long

Public Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal Hdc As Long) As Long

Public Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long

Public

Declare Function SetDIBColorTable Lib "gdi32" (ByVal Hdc As Long, ByVal

un1 As Long, ByVal un2 As Long, pcRGBQuad As RGBQUAD) As Long

Public

Declare Function GetDIBColorTable Lib "gdi32" (ByVal Hdc As Long, ByVal

un1 As Long, ByVal un2 As Long, pRGBQuad As RGBQUAD) As Long

Public Declare Function SelectObject Lib "gdi32.dll" (ByVal Hdc As Long, ByVal hObject As Long) As Long

Public

Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As

Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long,

ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal

dwRop As Long) As Long

Public Declare Function SetStretchBltMode Lib "gdi32" (ByVal Hdc As Long, ByVal nStretchMode As Long) As Long

Public

Declare Function StretchBlt Lib "gdi32" (ByVal Hdc As Long, ByVal X As

Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long,

ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal

nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As

Long

Public Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal Hdc

As Long, ByVal X As Long, ByVal Y As Long, ByVal dx As Long, ByVal dy

As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long,

ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, ByVal

wUsage As Long) As Long

Public Declare Function GetTickCount Lib "kernel32" () As Long

Public Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long

Public Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long

類模塊、CImage;文件名CImage.cls

Option Explicit

Private m_Width As Long '層的寬度

Private m_Height As Long '層的高度

Private m_Stride As Long '層數據每個掃描行的大小

Private m_Hdc As Long '層的內存DC

Private m_Pointer As Long '層數據在內存的首地址w

Private m_Handle As Long 'DIBSection的句柄

Private m_OldHandle As Long '原始設備環境的句柄

Public Property Get Width() As Long

Width = m_Width

End Property

Public Property Get Height() As Long

Height = m_Height

End Property

Public Property Get Stride() As Long

Stride = m_Stride

End Property

Public Property Get Hdc() As Long

Hdc = m_Hdc

End Property

Public Property Get Handle() As Long

Handle = m_Handle

End Property

Public Property Get Pointer() As Long

Pointer = m_Pointer

End Property

Private Sub Class_Terminate()

DisposeResource

End Sub

Public Function CreateNewImage(ByVal Width As Long, _ ByVal Height As Long) As Boolean

Dim ScreenDC As Long, BmpInfo As BITMAPINFOHEADER

If Width <= 0 Or Height <= 0 Then Exit Function

DisposeResource '刪除原始的內存資源

With BmpInfo

.BitCount = 24

.Height = -Height '為了和GDI對象的坐標系統(起點坐標在左上角),建立壹個倒序的DIB

.Width = Width

.Planes = 1

.Size = 40

m_Stride = ((Width * 3 + 3) And &HFFFFFFFC)

.SizeImage = m_Stride * Height

End With

ScreenDC = GetDC(0) '得到屏幕DC

m_Hdc = CreateCompatibleDC(ScreenDC)

ReleaseDC 0, ScreenDC '釋放屏幕DC

m_Handle = CreateDIBSection(m_Hdc, BmpInfo, DIB_RGB_COLORS, m_Pointer, 0, 0)

If m_Handle <> 0 Then '希望系統能夠讓我們成功創建DIB吧

m_OldHandle = SelectObject(m_Hdc, m_Handle)

m_Width = Width: m_Height = Height

CreateNewImage = True

End If

End Function

Public Sub DisposeResource()

If m_Hdc <> 0 Then

SelectObject m_Hdc, m_OldHandle

DeleteDC m_Hdc

DeleteObject m_Handle

m_Width = 0: m_Height = 0 '重置其他的圖像相關屬性

m_Handle = 0: m_OldHandle = 0

m_Pointer = 0: m_Hdc = 0

End If

End Sub

Public Function Render(ByVal DestDC As Long, _

Optional ByVal DestX As Long, _

Optional ByVal DestY As Long, _

Optional ByVal DestWidth As Long, _

Optional ByVal DestHeight As Long, _

Optional ByVal SrcX As Long, _

Optional ByVal SrcY As Long, _

Optional ByVal SrcWidth As Long, _

Optional ByVal SrcHeight As Long) As Boolean

If m_Handle = 0 Then Exit Function

If DestWidth = 0 Then DestWidth = m_Width

If DestHeight = 0 Then DestHeight = m_Height

If SrcX < 0 Then SrcX = 0 ' 源X,Y不能為負,但目的X,Y可以

If SrcY < 0 Then SrcY = 0

If SrcWidth = 0 Then

SrcWidth = m_Width

ElseIf SrcWidth < 0 Then

DestWidth = -DestWidth

SrcWidth = -SrcWidth

End If

If SrcHeight = 0 Then

SrcHeight = m_Height

ElseIf SrcHeight < 0 Then

DestHeight = -DestHeight

SrcHeight = -SrcHeight

End If

SetStretchBltMode DestDC, STRETCH_HALFTONE

StretchBlt DestDC, DestX, DestY, DestWidth, DestHeight, m_Hdc, SrcX, SrcY, SrcWidth, SrcHeight, vbSrcCopy

End Function

Public Function LoadPictureFromFile(FileName As String) As Boolean

Dim Width As Long, Height As Long

Dim StdPic As StdPicture

On Error GoTo Errhandle:

Set StdPic = LoadPicture(FileName)

Width = ConvertHimetrixToPixels(StdPic.Width, True)

Height = ConvertHimetrixToPixels(StdPic.Height, False)

If CreateNewImage(Width, Height) = True Then

StdPic.Render m_Hdc + 0&, 0&, 0&, Width + 0&, Height +

0&, 0, StdPic.Height, StdPic.Width, -StdPic.Height, ByVal 0

'類似於BMP的逆序存儲,所以用-StdPic.Height

LoadPictureFromFile = True

End If

Errhandle:

End Function

Private Function ConvertHimetrixToPixels(HiMetrix As Long, Horizontally As Boolean) As Long

If Horizontally Then

ConvertHimetrixToPixels = HiMetrix * 1440 / 2540 / Screen.TwipsPerPixelX

Else

ConvertHimetrixToPixels = HiMetrix * 1440 / 2540 / Screen.TwipsPerPixelY

End If

End Function

Private Function ConvertPixelsToHimetrix(Pixels As Long, Horizontally As Boolean) As Long

If Horizontally Then

ConvertPixelsToHimetrix = Pixels * Screen.TwipsPerPixelX * 2540 / 1440

Else

ConvertPixelsToHimetrix = Pixels * Screen.TwipsPerPixelY * 2540 / 1440

End IfEnd Function

  • 上一篇:又壹國家級重大開放平臺,長沙臨空經濟示範區獲批
  • 下一篇:如何對外包的項目進行驗收測試 詳細?0?3
  • copyright 2024編程學習大全網