會員登入 新使用者?立即註冊

在這裡搜集在知識+(K+)回答問題的精要,經過重新整理和安排,再加上參考資料的連結,希望讓同好能有進一步研究探討的互動平台。

關閉
你好,歡迎參觀我的部落格! 我要留言

存成JPEG(jpg)圖形檔

分類:影像處理
2010/01/08 16:13

在VB(.Net)中如何存成JPEG(jpg)圖形檔?



因為JPEG圖形檔的檔案大小不大,常常見到在網路上傳送,而且方便透過隨身碟來攜帶。在程式中,如果能將處理好的圖形資料直接存成JPEG圖形檔,真的是好酷喔!在本文中,將介紹數種存成JPEG圖形檔的方法和讀者分享。



使用VB.Net的類別或內建控制項

VB.Net的Bitmap類別和Image類別,可以直接將圖形存成JPEG圖形檔。下列的程式碼會以內定的75%品質(Quality或稱為壓縮比)來儲存JPEG圖形檔。

' 載入圖形檔
Dim bmpPic As New Bitmap("指定圖形檔的路徑和檔名")
或
Dim bmpPic As Image = Image.FromFile("指定圖形檔的路徑和檔名")

...

' 存成JPEG圖形檔,內定為75%的品質。
bmpPic.Save("指定jpg檔的路徑和檔名", ImageFormat.Jpeg)


同樣我們也可將VB.Net的PictureBox控制項中圖形,直接存成JPEG圖形檔。

' 載入圖形檔
PictureBox1.Image=New Bitmap("指定圖形檔的路徑和檔名")
或
PictureBox1.Image=Image.FromFile("指定圖形檔的路徑和檔名")

...

' 存成JPEG(jpg)圖形檔,內定為75%的品質。
PictureBox1.Image.Save("指定jpg檔的路徑和檔名", ImageFormat.Jpeg)


另外在儲存JPEG圖形檔時,可以使用EncoderParameters和EncoderParameter兩個類別,來改變其儲存的品質。

使用.Net Framework的類別

我們可以搭配FileStream、JpegBitmapEncoder和BitmapSource等三個類別,來儲存JPEG圖形檔。
其中JpegBitmapEncoder類別和BitmapSource類別的命名空間(Namespace)為

System.Windows.Media.Imaging

,並且必須參考PresentationCore.dll和WindowsBase.dll兩個dll檔,他們在

C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0

路徑中。

Imports System.IO
Imports System.Windows.Media.Imaging
Imports System.Drawing.Imaging

...

' 使用Bitmap類別或Image類別來載入圖形檔
' 當然亦可用PictureBox控制項來載入圖形檔
Dim bmpPic As New Bitmap("指定圖形檔的路徑和檔名")
或
Dim image As Image = System.Drawing.Image.FromFile("指定圖形檔的路徑和檔名")
Dim bmpPic As Bitmap = CType(image, Bitmap)
或
PictureBox1.Image = System.Drawing.Image.FromFile("指定圖形檔的路徑和檔名")
Dim bmpPic As Bitmap = CType(PictureBox1.Image, Bitmap)

...

' 設定相關資訊
Dim width As Integer = bmpPic.Width
Dim height As Integer = bmpPic.Height
Dim stride As Integer = (32 / 8) * width

' 取得指向圖形位元資料的指標
Dim srcRect As New Rectangle(0, 0, width, height)
Dim bmpSrcData As BitmapData = bmpPic.LockBits( _
    srcRect, _
    ImageLockMode.ReadOnly, _
    System.Drawing.Imaging.PixelFormat.Format32bppRgb)
Dim bmpSrcPtr As IntPtr = bmpSrcData.Scan0

' 使用FileStream類別來儲存jpg檔
Dim imageStreamTarget As New FileStream( _
    "指定jpg檔的路徑和檔名", _
    FileMode.Create)

' 使用BitmapSource類別來建立圖形資訊
Dim bmpSource As BitmapSource = BitmapSource.Create( _
    width, _
    height, _
    96, _
    96, _
    System.Windows.Media.PixelFormats.Bgr32, _
    Nothing, _
    bmpSrcPtr, _
    height * stride, _
    stride)

' 使用JpegBitmapEncoder來進行編碼
' 並且指定75%的儲存品質
Dim encoder As New JpegBitmapEncoder()
encoder.QualityLevel = 75
encoder.Frames.Add(BitmapFrame.Create(bmpSource))
encoder.Save(imageStreamTarget)

' 釋放imageStreamTarget物件
imageStreamTarget.Close()
imageStreamTarget.Dispose()

' 釋放bmpPic物件
bmpPic.UnlockBits(bmpSrcData)
bmpPic.Dispose()


讀者們或許已注意到,以上的程式碼在System.Drawing.Imaging和System.Windows.Media.Imaging兩個命名空間之間共用圖形的位元資料。

使用Intel JPEG Library (IJL)

在VB(.Net)中可以透過Intel的JPEG程式庫(IJL),將圖形儲存成JPEG圖形檔。但必須要有此程式庫的DLL動態連結檔,如ijl11.dll、ijl15.dll或ijl20.dll等。

首先要初始化Intel的JPEG程式庫。

Dim jcprops As JPEG_CORE_PROPERTIES
Dim jerr As IJLERR

jerr = ijlInit(jcprops)


載入圖形檔,並取得圖形的相關資訊。

' 使用PictureBox控制項或Image控制項來載入圖形檔
' 當然亦可用來StdPicture物件載入圖形檔
Picture1.Picture = LoadPicture("指定圖形檔的路徑和檔名")
或
Image1.Picture = LoadPicture("指定圖形檔的路徑和檔名")
或
Dim stdPic As StdPicture
Set stdPic = LoadPicture("指定圖形檔的路徑和檔名")

...

' 取得圖形的相關資訊
Dim bmp As BITMAP

GetObject Picture1.Picture, Len(bmp), bmp
或
GetObject Image1.Picture, Len(bmp), bmp
或
GetObject stdPic.Handle, Len(bmp), bmp

...

Dim picWidth As Long, picHeight As Long

picWidth = bmp.bmWidth
picHeight = bmp.bmHeight


將圖形的位元資料,載入配置的緩衝區中。

' 配置緩衝區
Dim NumBits As Long
Dim hMemBitsData As Long, lpBitsData As Long
   
NumBits = ((picWidth * (bmp.bmBitsPixel / 8) + 3) _
          And &HFFFFFFFC) * picHeight
hMemBitsData = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, NumBits)
lpBitsData = GlobalLock(hMemBitsData)

' 取得圖形位元資料
Dim bmpInfo As BITMAPINFO

With bmpInfo.bmiHeader
 .biSize = Len(bmpInfo.bmiHeader)
 .biWidth = bmp.bmWidth
 .biHeight = bmp.bmHeight
 .biPlanes = bmp.bmPlanes
 .biBitCount = bmp.bmBitsPixel
 .biCompression = BI_RGB
End With

GetDIBits Picture1.hDC, _
          Picture1.Image, _
          0, _
          picHeight, _
          lpBitsData, _
          bmpInfo, _
          DIB_RGB_COLORS
或
Dim hDCmem As Long
hDCmem = CreateCompatibleDC(Me.hDC)
SelectObject hDCmem, Image1.Picture
GetDIBits hDCmem, Image1, 0, picHeight, lpBitsData, bmpInfo, DIB_RGB_COLORS
DeleteDC hDCmem
或
Dim hDCmem As Long
hDCmem = CreateCompatibleDC(Me.hDC)
SelectObject hDCmem, stdPic.Handle
GetDIBits hDCmem, _
          stdPic.Handle, _
          0, _
          picHeight, _
          lpBitsData, _
          bmpInfo, _
          DIB_RGB_COLORS
DeleteDC hDCmem


設定壓縮JPEG圖形檔的相關資訊,並且進行壓縮處理。

' 設定DIB資訊
jcprops.DIBWidth = picWidth
jcprops.DIBHeight = -picHeight
jcprops.DIBPadBytes = ((picWidth * (bmp.bmBitsPixel / 8) + 3) _
                      And &HFFFFFFFC) - picWidth * 3

' 取得指向圖形位元資料的指標
jcprops.DIBBytes = lpBitsData

' 設定JPEG資訊
jcprops.JPGWidth = picWidth
jcprops.JPGHeight = picHeight
    
' 設定儲存時的品質百分比
jcprops.jquality = 75

' 設定JPEG緩衝區,存放壓縮後的結果。
Dim buf() As Byte, lBufSize As Long, lBufPtr As Long

lBufSize = jcprops.JPGWidth * jcprops.JPGHeight * 4
ReDim buf(0 To lBufSize - 1) As Byte
lBufPtr = VarPtr(buf(0))

jcprops.JPGBytes = lBufPtr
jcprops.JPGSizeBytes = lBufSize

' 進行壓縮處理
jerr = ijlWrite(jcprops, IJL_JBUFF_WRITEWHOLEIMAGE)


壓縮後,進行存檔處理。

' 取得壓縮後的資料
Dim fb() As Byte
      
lBufSize = jcprops.JPGSizeBytes
ReDim fb(0 To lBufSize - 1) As Byte
      
CopyMemory fb(0), ByVal lBufPtr, lBufSize

' 進行存檔處理
Dim iFile As Long, sFile As String
      
sFile = "指定jpg檔的路徑和檔名"
iFile = FreeFile()
Open sFile For Binary Access Write As #iFile
Put #iFile, , fb()
Close #iFile


最後記得釋放緩衝區。

...

GlobalUnlock hMemBitsData
GlobalFree hMemBitsData


也要記得釋放Intel的JPEG程式庫。

...

ijlFree jcprops


使用GDI Plus

在VB(.Net)中透過呼叫GDI+(gdiplus.dll)的API,我們也可將圖形儲存成JPEG圖形檔。

首先要初始化GDI+l程式庫。

Dim GDIpInit As GdiplusStartupInput
Dim Token As Long

...

GDIpInit.GdiplusVersion = 1
GdiplusStartup Token, GDIpInit, ByVal 0&


載入圖形檔。

' 使用PictureBox控制項或Image控制項來載入圖形檔
' 當然亦可用來StdPicture物件載入圖形檔
Picture1.Picture = LoadPicture("指定圖形檔的路徑和檔名")
或
Image1.Picture = LoadPicture("指定圖形檔的路徑和檔名")
或
Dim stdPic As StdPicture
Set stdPic = LoadPicture("指定圖形檔的路徑和檔名")

...



現在就可以將圖形存成JPEG圖形檔了。

Dim Img As Long

' 將GDI的hBitmap轉為GDI+的Image
GdipCreateBitmapFromHBITMAP Picture1.Picture, 0&, img
或
GdipCreateBitmapFromHBITMAP Image1.Picture, 0&, img
或
GdipCreateBitmapFromHBITMAP stdPic.Handle, 0&, img

' 取得JPEG編碼的CLSID
Dim encoderCLSID As CLSID
GetEncoderClsid "image/jpeg", encoderCLSID

' 設定儲存時的品質百分比
Dim encoderParams As EncoderParameters
' 參數陣列中只有一個元素
encoderParams.Count = 1
With encoderParams.Parameter
 .NumberOfValues = 1                    ' 設定為1
 .Type = EncoderParameterValueTypeLong  ' 資料型態為32位元Unsigned Integer
 GetParameterGUID EncoderQuality, .Guid ' 設定參數為EncoderQuality
 .Value = VarPtr(75)                    ' 參數的值為75,但為指標。
End With

' 進行存檔
GdipSaveImageToFile img, _
                    StrConv("指定jpg檔的路徑和檔名", vbUnicode), _
                    encoderCLSID, _
                    encoderParams)


最後要記得釋放Image物件。

...

GdipDisposeImage Img


也要記得釋放GDI+l程式庫。

...

GdiplusShutdown Token


瞭解JPEG檔

如果我們能夠充分的瞭解JPEG檔的壓縮原理和JPEG檔的檔案格式,我們就可以自行撰寫程式來儲存JPEG檔。在Wikipedia網站中就有詳細介紹JPEG檔的網頁,另外由korejwa撰寫的JPEG Encoder類別模組(VB6),在未使用Intel的JPEG程式庫(IJL)狀況下,直接將圖形存成JPEG圖形檔。

' 載入圖形檔
Dim MyPic As StdPicture
Set MyPic = LoadPicture("指定圖形檔的路徑和檔名")

...

' 存成JPEG圖形檔
Dim m_Image As New cImage
m_Image.CopyStdPicture MyPic

Dim m_Jpeg As New cJpeg
m_Jpeg.Quality = 75
m_Jpeg.SampleHDC m_Image.hDC, m_Image.Width, m_Image.Height
m_Jpeg.SaveFile "指定jpg檔的路徑和檔名"

' 清除物件
Set m_Image = Nothing
Set m_Jpeg = Nothing


 

問題延伸...

 

相關網頁連結...



上一篇 下一篇
回應(0)
引用(0)
  1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

統計資料

  • 今日人數:5
  • 累計人數:4119
  • 發表文章:28
  • 相片數量:0
  • 回應數量:7

搜尋

雅虎資訊 版權所有 © 2013 Yahoo! Taiwan All Rights Reserved
「本服務設有管理員」 服務條款 隱私權政策