社区
图形处理/算法
帖子详情
BITMAPINFO结果中的biSizeImage如何算?
chengwei02
2007-09-29 01:25:16
我在网上搜到一个公式
biSizeImage=(biWidth*biBitCount+31)/32*4*biHeight
不知道为啥加31
...全文
820
3
打赏
收藏
BITMAPINFO结果中的biSizeImage如何算?
我在网上搜到一个公式 biSizeImage=(biWidth*biBitCount+31)/32*4*biHeight 不知道为啥加31
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
3 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
jizexuan3681
2007-10-01
打赏
举报
回复
补齐,存储要求,楼上已经解释的足够清楚了~呵呵,开凑个热闹!
carfieldlee
2007-09-29
打赏
举报
回复
biSizeImage=(biWidth*biBitCount+31)/32*4*biHeight其中,biWidth*biBitCount是每一行图像占用的位数,除以8是每行图像占用的字节数,要为4的整数倍,所以除以32再乘以4
31是按整数除法自动取整的原则来的,其保证每行图像字节数必须是4的整倍数!
举一个例子,对于2色图,如果图象宽是31,则每一行需要31位存储,合3个字节加7位,因为字节数必须是4的整倍数,所以应该是4。所以补齐时需要加上4个字节数即32位
vcPlayer
2007-09-29
打赏
举报
回复
BMP位图要求一行的字节数为4的整数倍,4字节就是32位,根据整数除法的规则,所以加31(这其实就是数学上的取整运算的计算机实现)!
(biWidth*biBitCount+31)/32*4 公式算出来的是一行的字节数。
视屏截图代码
void CScreenServerDlg::GetPicutueData() { CDC* pDeskDC = GetDesktopWindow()->GetDC(); //获取桌面画布对象 CRect rc; GetDesktopWindow()->GetClientRect(rc); //获取屏幕的客户区域 CDC memDC; //定义一个内存画布 memDC.CreateCompatibleDC(pDeskDC); //创建一个兼容的画布 C
Bi
tmap
bmp; bmp.CreateCompatible
Bi
tmap
(pDeskDC,rc.Width(),rc.Height()); //创建兼容位图 memDC.SelectObject(&bmp); //选
中
位图对象
BI
TMAP
bi
tmap
; bmp.Get
Bi
tmap
(&
bi
tmap
); int panel
size
= 0; //记录调色板大小 if (
bi
tmap
.bm
Bi
tsPixel<16) //判断是否为真彩色位图 panel
size
= pow(2,
bi
tmap
.bm
Bi
tsPixel*
size
of(RGBQUAD));
BI
TMAP
INFO
*p
BI
nfo = (
BI
TMAP
INFO
*)LocalAlloc(LPTR,
size
of(
BI
TMAP
INFO
)+panel
size
); p
BI
nfo->bmiHeader.
bi
Bi
tCount =
bi
tmap
.bm
Bi
tsPixel; p
BI
nfo->bmiHeader.
bi
ClrImportant = 0; p
BI
nfo->bmiHeader.
bi
Compression = 0; p
BI
nfo->bmiHeader.
bi
Height =
bi
tmap
.bmHeight; p
BI
nfo->bmiHeader.
bi
Planes =
bi
tmap
.bmPlanes; p
BI
nfo->bmiHeader.
bi
Size
=
size
of(
BI
TMAP
INFO
); p
BI
nfo->bmiHeader.
bi
Size
Image
=
bi
tmap
.bmWidthBytes*
bi
tmap
.bmHeight; p
BI
nfo->bmiHeader.
bi
Width =
bi
tmap
.bmWidth; p
BI
nfo->bmiHeader.
bi
XPelsPerMeter = 0; p
BI
nfo->bmiHeader.
bi
YPelsPerMeter = 0;
linux下 将uyvy格式图片转换成bmp格式
在linux下,将uyvy格式的图片转换成bmp格式 默认宽度是720 头文件忘记传了:uyvytobmp.h #ifndef __UYVY_TO_BMP__ #define __UYVY_TO_BMP__ typedef unsigned int DWORD; typedef unsigned short int WORD; typedef unsigned char BYTE; typedef long LONG; #define clip(min, x, max) x=(x max) ? max : x #define
BI
_RGB 0L typedef struct tagTABLE_UYVY2RGB { unsigned short YtoR[256]; unsigned short YtoG[256]; unsigned short YtoB[256]; unsigned short UtoG[256]; unsigned short UtoB[256]; unsigned short VtoR[256]; unsigned short VtoG[256]; }TABLE_UYVY2RGB; TABLE_UYVY2RGB table_UYVY2rgb; typedef struct tag
BI
TMAP
FILEHEADER { DWORD bfOff
Bi
ts; DWORD bf
Size
; WORD bfType; WORD bfReserved1; WORD bfReserved2; }
BI
TMAP
FILEHEADER; typedef struct tag
BI
TMAP
INFO
HEADER{ DWORD
bi
Size
; LONG
bi
Width; LONG
bi
Height; WORD
bi
Planes; WORD
bi
Bi
tCount; DWORD
bi
Compression; DWORD
bi
Size
Image
; LONG
bi
XPelsPerMeter; LONG
bi
YPelsPerMeter; DWORD
bi
ClrUsed; DWORD
bi
ClrImportant; }
BI
TMAP
INFO
HEADER; typedef struct tagRGBQUAD { BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; } RGBQUAD; typedef struct tag
BI
TMAP
INFO
{
BI
TMAP
INFO
HEADER bmiHeader; RGBQUAD bmiColors[1]; }
BI
TMAP
INFO
; #endif
DIBSection Class VB
What is a DIB Section?
A DIB (Device Independent
Bi
tmap
) Section is a GDI object like a standard DIB but which additionally provides a pointer to the memory used to store the
bi
tmap
bi
ts to which the creating application has direct access. This allows ultimate flexi
bi
lity if you want to modify the
bi
ts of a
bi
tmap
.
Using DIB Sections
A DIB section is created using the GDI CreateDIBSection call. You need to modify the declare provided for this in the VB API guide because this declare assumes you cannot use the pointer to the
bi
tmap
returned by the function and simply discards it. Here are the declares you need:
Private Type
BI
TMAP
INFO
HEADER '40 bytes
bi
Size
As Long
bi
Width As Long
bi
Height As Long
bi
Planes As Integer
bi
Bi
tCount As Integer
bi
Compression As Long
bi
Size
Image
As Long
bi
XPelsPerMeter As Long
bi
YPelsPerMeter As Long
bi
ClrUsed As Long
bi
ClrImportant As Long
End Type
Private Type
BI
TMAP
INFO
bmiHeader As
BI
TMAP
INFO
HEADER
bmiColors As RGBQUAD
End Type
' Note - this is not the declare in the API viewer - modify lplpVoid to be
' Byref so we get the pointer back:
Private Declare Function CreateDIBSection Lib "gdi32" _
(ByVal hdc As Long, _
p
Bi
tmap
Info
As
BI
TMAP
INFO
, _
ByVal un As Long, _
lplpVoid As Long, _
ByVal handle As Long, _
ByVal dw As Long) As Long
To create the DIB Section, you initialise a
BI
TMAP
INFO
structure with the required fields, which are all in the bmiHeader sub-structure:
Member Required Value
bi
Size
Size
of the
BI
TMAP
INFO
structure
bi
Width Width of the DIBSection in pixels
bi
Height Height of the DIBSection in pixels
bi
Planes Number of colour planes. Set to 1
bi
Bi
tCount
Bi
ts per pixel. Set to 24 for true colour
bi
Compression Whether to use compression. If you want to work on the
bi
ts, set this to
BI
_RGB so the
image
is uncompressed
bi
Size
Image
The
size
of the
image
in bytes. This is worked out from the width, height, number of
bi
ts per pixel. In a 24
bi
t
image
there are three bytes per pixel. Additionally, GDI requires that every horizontal line in the
image
aligns on a four byte boundary. So for a 24
bi
t
image
the
Image
Size
is
bi
Width*
bi
Height*3 rounded up to the nearest four bytes. You can round up to the width to the nearest four bytes as follows:
(.
bi
Width * 3 + 3) And &HFFFFFFFC
This allows you to create a DIB Section. You call CreateDIBSection like this:
hDib = CreateDIBSection( _
lHDC, _
m_t
BI
, _
DIB_RGB_COLORS, _
m_lPtr, _
0, 0)
Where:
hDib is a variable to receive the GDI handle to the DIB Section
lHDC is a valid DC, for example a Form's DC or the desktop DC
m_t
BI
is a the
BI
TMAP
INFO
structure
m_lPtr is a variable to receive the pointer to the memory containing the
bi
tmap
bi
ts.
To actually display a DIB Section, you must select it into a DC.
m_hDC = CreateCompatibleDC(0)
If (m_hDC <> 0) Then
If (CreateDIB(m_hDC, lWidth, lHeight, m_hDIb)) Then
m_hBmpOld = SelectObject(m_hDC, m_hDIb)
Create = True
Else
DeleteObject m_hDC
m_hDC = 0
End If
End If
Once it is in a DC you can then use
Bi
tBlt to paint it to another device context or to transfer the contents of another device context into it. Remember you must keep track of all the handles created in GDI so you can clear them up again when the DIBSection is no longer needed. To clear up, you need to:
Select the old
bi
tmap
(m_hBmpOld) back into the DC.
Delete the DIB section.
Delete the DC.
So far this has created a DIB which you can load with a graphic and display on the screen, but this achieves no more than you can do with a standard
bi
tmap
. The good stuff starts when you start modifying the
bi
tmap
bi
ts.
Modifying the
Bi
tmap
Bi
ts Directly
CreateDIBSection returns an address to the memory containing the
bi
tmap
. You can manipulate this directly through VB using a cool technique to make the memory look like a VB Byte array. This technique was originally presented in VBPJ article (Note the original article is no longer easily available). It uses a hidden VB call exposed by MSVBVM50.DLL (which is also available in VB6 - thanks to Paul Wilde for pointing this out) and the u
bi
quitous CopyMemory call. In my opinion, “CopyMemory” is the best language feature in VB (except that it isn't VB at all!)
Here are the declares you need:
Private Type SAFEARRAY2D
cDims As Integer
fFeatures As Integer
cbElements As Long
cLocks As Long
pvData As Long
Bounds(0 To 1) As SAFEARRAYBOUND
End Type
Private Declare Function VarPtrArray Lib "msvbvm50.dll" Alias "VarPtr" (Ptr() As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
To make the byte array point to the memory, you have to fill in the SAFEARRAY2D structure and then use CopyMemory as follows:
Dim tSA As SAFEARRAY2D
Dim bDib() As Byte
' Get the
bi
ts in the from DIB section:
With tSA
.cbElements = 1
.cDims = 2
.Bounds(0).lLbound = 0
' Height of the
bi
tmap
.Bounds(0).cElements = m_t
BI
.bmiHeader.
bi
Height
.Bounds(1).lLbound = 0
' Width of the
bi
tmap
in
bi
ts (see earlier):
.Bounds(1).cElements = BytesPerScanLine()
.pvData = m_lPtr
End With
' Make the bDib() array point to the memory addresses:
CopyMemory ByVal VarPtrArray(bDib()), VarPtr(tSA), 4
Now the bDib() array is a two dimensional array with the first dimension being the x values and the second being the y values. A 24
bi
t DIB section is arranged so the bytes run Blue, Green, Red and remember that since the array is padded to a DWORD boundary there may be up to three unused bytes at the end of each row. So, for example, to set the top left pixel to purple you would write this:
bDib(0,0) = 255 ' Blue
bDib(1, 0) = 0 ' Green
bDib(2, y) = 255 ' Red
Once you have finished with the bDib array, you need to be sure to clear up the SAFEARRAY pointer you have created. If you fail to do this, your code will work under Win9x but will crash NT4.0:
CopyMemory ByVal VarPtrArray(bDib), 0&, 4
Enough of That, I Want to Use It
That covers the theory of using DIB Sections. To make it easy, I include a self-contained class (cDibSection) which you can include. The implementation is as follows:
Method Description
BytesPerScanLine Returns the number of bytes horizontally, taking into account the
bi
ts per pixel and 4 byte boundary padding.
ClearUp Frees up any GDI objects held by the class. Called automatically when the class terminates.
CopyToClipboard Does as it says!
Create Creates a DIB section of the specified width and height in pixels.
CreateFromPicture Creates a DIB section the same
size
as a VB picture object and copies the
bi
tmap
in it into the DIB section.
DIBSection
Bi
tsPtr Returns the address of the DIBSection's
bi
ts in memory.
hdc Returns the memory device context used by the class to hold the DIB Section. You can use this in GDI operations, but do not call DeleteObject on it.
hDib Returns a handle to the DIBSection held by the class. You can use this in GDI operations, but do not call DeleteObject on it.
Height Returns the Height of the DIBSection in pixels.
LoadPictureBlt Copies all or a part of a picture from another Device Context into the DIB section.
PaintPicture Similar to the VB paint picture method, this copies all or part of the DIB section to another device context using the specified Raster Operation.
Randomise
Bi
ts Randomises the pixels in the DIB Section, either to random colours or gray scaled.
Resample Re
size
s the DIB using linear interpolation to create a smoother re
size
d version than you would get if you used StretchBlt.
Width Returns the width of the DIB in pixels.
A Simple Fade Example
This demonstrates how to fade out a
bi
tmap
. It should run as a real-time animation, provided the
image
size
isn't too
bi
g. I've found that
image
s which are too large don't show as a smooth animation even when the fade code runs quickly enough because
Bi
tBlt tends to "tear". This occurs because
Bi
tBlt doesn't completely display the
bi
tmap
during a single screen refresh and therefore the
image
is partially displayed before the refresh occurs. To get round this problem you need to use DirectX.
This sample is simplified version of the static and fade example available for download on the
Image
Processing using DIB Sections page.
To try this sample, create a new project and add the cDIBSection class to it. Copy the declares for CopyMemory, VarPtrArray and SAFEARRAY2D into the project's form.
Then add this sub:
Private Sub Fade( _
ByRef cTo As cDIBSection, _
ByVal lAmount As Long _
)
Dim bDib() As Byte
Dim x As Long, y As Long
Dim xMax As Long, yMax As Long
Dim lB As Long, lG As Long, lR As Long
Dim lA As Long, lA2 As Long
Dim lTIme As Long
Dim tSA As SAFEARRAY2D
' have the local matrix point to
bi
tmap
pixels
With tSA
.cbElements = 1
.cDims = 2
.Bounds(0).lLbound = 0
.Bounds(0).cElements = cTo.Height
.Bounds(1).lLbound = 0
.Bounds(1).cElements = cTo.BytesPerScanLine
.pvData = cTo.DIBSection
Bi
tsPtr
End With
CopyMemory ByVal VarPtrArray(bDib), VarPtr(tSA), 4
yMax = cTo.Height - 1
xMax = cTo.Width - 1
For x = 0 To (xMax * 3) Step 3
For y = 0 To yMax
lB = lAmount * bDib(x, y) \ 255
lG = lAmount * bDib(x + 1, y) \ 255
lR = lAmount * bDib(x + 2, y) \ 255
bDib(x, y) = lB
bDib(x + 1, y) = lG
bDib(x + 2, y) = lR
Next y
Next x
CopyMemory ByVal VarPtrArray(bDib), 0&, 4
End Sub
Add a Command Button to the Form, and put this code behind it:
Private Sub Command1_Click()
Dim cDib As New cDibSection
Dim cDibBuffer as New cDibSection
Dim i As Long
' Load the picture to fade:
Set sPic = LoadPicture("Put Your File Here!")
cDib.CreateFromPicture sPic
' Create a copy of it:
cDibBuffer.Create cDib.Width, cDib.Height
cDib.PaintPicture cDibBuffer.HDC
' Fade Loop:
For i = 0 To 255 Step 4
' Fade the dib by amount i:
Fade cDib, i
' Draw it:
cDib.PaintPicture Form1.hDC
' Breathe a little. You may have to put a slowdown here:
DoEvents
' Reset for next fade:
cDibBuffer.PaintPicture cDib.HDC
Next i
End Sub
Now run the code. When you click the button, the
image
will be faded as fast as your system allows. The code will run slowly in the IDE but will go much much quicker if you compile it to native code. Also, checking all the Advanced Optimisation settings will make it run about 60% faster again! On my machine (PII 266 with 8Mb Xpert@Work card) it does 40fps when working on a 256x256 pixel
image
.
Using DIB Sections in VB
Using DIB Sections in VB An Easy to Use Class for manipulating DIBSections plus a blindingly quick technique for updating the
bi
ts Updated! 17 February 1999 The previous version of this code crashed when run under NT4.0. This was because the code was not always clearing up the SAFEARRAY pointer after it had finished using it. Under Win9x, this did not cause a problem but NT is stricter. All the samples and the code are now updated to fix this problem. This is a supporting article descri
bi
ng in more detail the DIB Section techniques used in the vbAccelerator
Image
Processor. It describes what DIB Sections are, how to use them and provides a class I wrote to wrap up the DIB Section. What is a DIB Section?A DIB (Device Independent
Bi
tmap
) Section is a GDI object like a standard DIB but which additionally provides a pointer to the memory used to store the
bi
tmap
bi
ts to which the creating application has direct access. This allows ultimate flexi
bi
lity if you want to modify the
bi
ts of a
bi
tmap
. Using DIB SectionsA DIB section is created using the GDI CreateDIBSection call. You need to modify the declare provided for this in the VB API guide because this declare assumes you cannot use the pointer to the
bi
tmap
returned by the function and simply discards it. Here are the declares you need:Private Type
BI
TMAP
INFO
HEADER '40 bytes
bi
Size
As Long
bi
Width As Long
bi
Height As Long
bi
Planes As Integer
bi
Bi
tCount As Integer
bi
Compression As Long
bi
Size
Image
As Long
bi
XPelsPerMeter As Long
bi
YPelsPerMeter As Long
bi
ClrUsed As Long
bi
ClrImportant As Long End Type Private Type
BI
TMAP
INFO
bmiHeader As
BI
TMAP
INFO
HEADER bmiColors As RGBQUAD End Type ' Note - this is not the declare in the API viewer - modify lplpVoid to be ' Byref so we get the pointer back:
BI
TMAP
INFO
结构详解
BI
TMAP
INFO
结构定义了Windows设备无关位图(DIB)的度量和颜色信息 typedef struct tag
BI
TMAP
INFO
{ // bmi
BI
TMAP
INFO
HEADER bmiHeader; //指定了一个
BI
TMAP
INFO
HEADER结构,包含了有关设备相关位图的度量和颜色格式的信息 RGBQUAD bmiColors[1]; /
图形处理/算法
19,468
社区成员
50,700
社区内容
发帖
与我相关
我的任务
图形处理/算法
VC/MFC 图形处理/算法
复制链接
扫一扫
分享
社区描述
VC/MFC 图形处理/算法
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章