`

JPEG文件数据结构以及将位图保存为JPG的代码 转2

阅读更多

三、实例分析
  用系统自带的画图程序画一个32×24的红色方块,另存为JPG文件,这个文件的全部数据如下:

0000: FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 00 60
0010: 00 60 00 00 FF DB 00 43 00 08 06 06 07 06 05 08
0020: 07 07 07 09 09 08 0A 0C 14 0D 0C 0B 0B 0C 19 12
0030: 13 0F 14 1D 1A 1F 1E 1D 1A 1C 1C 20 24 2E 27 20
0040: 22 2C 23 1C 1C 28 37 29 2C 30 31 34 34 34 1F 27
0050: 39 3D 38 32 3C 2E 33 34 32 FF DB 00 43 01 09 09
0060: 09 0C 0B 0C 18 0D 0D 18 32 21 1C 21 32 32 32 32
0070: 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32
0080: 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32
0090: 32 32 32 32 32 32 32 32 32 32 32 32 32 32 FF C0
00A0: 00 11 08 00 18 00 20 03 01 22 00 02 11 01 03 11
00B0: 01 FF C4 00 1F 00 00 01 05 01 01 01 01 01 01 00
00C0: 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09
00D0: 0A 0B FF C4 00 B5 10 00 02 01 03 03 02 04 03 05
00E0: 05 04 04 00 00 01 7D 01 02 03 00 04 11 05 12 21
00F0: 31 41 06 13 51 61 07 22 71 14 32 81 91 A1 08 23
0100: 42 B1 C1 15 52 D1 F0 24 33 62 72 82 09 0A 16 17
0110: 18 19 1A 25 26 27 28 29 2A 34 35 36 37 38 39 3A
0120: 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A
0130: 63 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A
0140: 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99
0150: 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7
0160: B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5
0170: D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 E8 E9 EA F1
0180: F2 F3 F4 F5 F6 F7 F8 F9 FA FF C4 00 1F 01 00 03
0190: 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01
01A0: 02 03 04 05 06 07 08 09 0A 0B FF C4 00 B5 11 00
01B0: 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00
01C0: 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13
01D0: 22 32 81 08 14 42 91 A1 B1 C1 09 23 33 52 F0 15
01E0: 62 72 D1 0A 16 24 34 E1 25 F1 17 18 19 1A 26 27
01F0: 28 29 2A 35 36 37 38 39 3A 43 44 45 46 47 48 49
0200: 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69
0210: 6A 73 74 75 76 77 78 79 7A 82 83 84 85 86 87 88
0220: 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5 A6
0230: A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4
0240: C5 C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA E2
0250: E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 F7 F8 F9
0260: FA FF DA 00 0C 03 01 00 02 11 03 11 00 3F 00 E2
0270: E8 A2 8A F9 93 F7 10 A2 8A 28 00 A2 8A 28 00 A2
0280: 8A 28 03 FF D9

分析:
0000-0001:FF D8(文件头)
0002-0013:APP0段,其中:
  0002-0003:FF E0(段标记)
  0004-0005:00 10(段长度=16字节)
  0006-000A:4A 46 49 46 00(“JFIF”的ASCII码)
  000B-000C:01 01(主次版本号=1.01)
  000D     :01(密度单位为 点数/英寸)
  000E-0011:00 60 00 60(水平和垂直的密度均为每英寸96像素)
  0012-0013:00 00(没有缩略图)
0014-0058:DQT段,其中:
  0014-0015:FF DB(段标记)
  0016-0017:00 43(段长度=67字节)
  0018     :00(QT号=0,QT精度=8bit)
  0019-0058:QT
0059-009D:DQT段,其中:
  0059-005A:FF DB(段标记)
  005B-005C:00 43(段长度=67字节)
  005D     :01(QT号=1,QT精度=8bit)
  005E-009D:QT
009E-00B0:SOF0段,其中:
  009E-009F:FF C0(段标记)
  00A0-00A1:00 11(段长度=17字节)
  00A2     :08(样本精度=8bit)
  00A3-00A6:00 18 00 20(图像高=24,图像宽=32)
  00A7     :03(组件数量=3,YCbCr彩色图)
  00A8     :01(ID号=1,这是亮度Y组件)
  00A9     :22(化为二进制=00100010,表明垂直和水平采样系数均=2)
  00AA     :00(使用QT号=0的量化表)
  00AB     :02(ID号=2,这是色度Cb组件)
  00AC     :11(化为二进制=00010001,表明垂直和水平采样系数均=1)
  00AD     :01(使用QT号=1的量化表)
  00AE     :03(ID号=3,这是色度Cr组件)
  00AF     :11(化为二进制=00010001,表明垂直和水平采样系数均=1)
  00B0     :01(使用QT号=1的量化表)
00B1-00D1:DHT段,其中:
  00B1-00B2:FF C4(段标记)
  00B3-00B4:00 1F(段长度=31字节)
  00B5     :00(HT号=0,DC表)
  00B6-00C5:这16个数字之和=12,说明下面的HT值表的长度=12字节)
  00C6-00D1:HT值表
00D2-0188:DHT段,这是HT号=0的AC表,参照上面分析
0189-01A9:DHT段,这是HT号=1的DC表,参照上面分析
01AA-0260:DHT段,这是HT号=1的AC表,参照上面分析
0261-026E:SOS段,其中:
  0261-0262:FF DA(段标记)
  0263-0264:00 0C(段长度=12字节)
  0265     :03(组件数量=3)
  0266-0267:01 00(组件ID=1,Y组件,使用HT表号=0的AC表)
  0268-0269:02 11(组件ID=2,Cb组件,使用HT表号=1的DC表)
  026A-026B:03 11(组件ID=3,Cr组件,使用HT表号=1的DC表)
  026C-026E:00 3F 00(几乎每个JPG文件中这3个字节的值都相同,但用途不明)
026F-0282:图像压缩数据
0283-0284:FF D9(文件尾)

 

作者:一江秋水      发表时间:2010-1-30 10:00:00

 3楼  


四、将位图保存为JPG的函数代码:

Option Explicit

Private Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id As GUID) As Long
Private Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Private Declare Function GdipCreateBitmapFromHBITMAP Lib "gdiplus" (ByVal hbm As Long, ByVal hpal As Long, Bitmap As Long) As Long
Private Declare Function GdiplusStartup Lib "gdiplus.dll" (ByRef token As Long, ByRef inputX As GdiplusStartupInput, ByVal Output As Long) As Long
Private Declare Function GdipSaveImageToFile Lib "gdiplus" (ByVal Image As Long, ByVal Filename As Long, clsidEncoder As GUID, encoderParams As Any) As Long
Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal Image As Long) As Long
Private Declare Function GdiplusShutdown Lib "gdiplus.dll" (ByVal token As Long) As Long

Private Type GUID
  Data1  As Long
  Data2  As Integer
  Data3  As Integer
  Data4(0 To 7) As Byte
End Type
Private Type GdiplusStartupInput
  GdiplusVersion As Long
  DebugEventCallback As Long
  SuppressBackgroundThread As Long
  SuppressExternalCodecs As Long
End Type
Private Type EncoderParameter
  GUID As GUID
  NumberOfvalues  As Long
  type As Long
  Value As Long
End Type
Private Type EncoderParameters
  Count As Long
  Parameter As EncoderParameter
End Type

'输入参数:必需的:1.对象;2.要保存的全路径文件名;可选的:3.jpg品质因素
Private Function SaveJpg(ByVal pict As StdPicture, ByVal Filename As String, Optional ByVal JPG_Quality As Byte = 80) As Boolean
On Error GoTo 100
Dim lGDIP As Long
Dim lBitmap As Long
Dim aEncParams() As Byte
Dim udtData As GdiplusStartupInput

udtData.GdiplusVersion = 1 'GDI+初始化
If GdiplusStartup(lGDIP, udtData, 0) = 0 Then
  If GdipCreateBitmapFromHBITMAP(pict.Handle, 0, lBitmap) = 0 Then '从句柄创建 GDI+ 图像
    Dim tJpgEncoder As GUID
    Dim tParams As EncoderParameters
    CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder '初始化解码器的GUID标识
    tParams.Count = 1      '设置解码器参数
    With tParams.Parameter '设置品质因数
      CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .GUID '获取JPG_Quality参数的GUID标识
      .NumberOfvalues = 1
      .type = 4
      .Value = VarPtr(JPG_Quality)
    End With
    ReDim aEncParams(1 To Len(tParams))
    Call CopyMemory(aEncParams(1), tParams, Len(tParams))
    GdipSaveImageToFile lBitmap, StrPtr(Filename), tJpgEncoder, aEncParams(1) '保存图像
    GdipDisposeImage lBitmap '销毁GDI+图像
    GdiplusShutdown lGDIP
    Erase aEncParams
    SavePic = True
  End If
End If
Exit Function
100
End Function

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics