Dim dl As Long
Dim bmpinfo As BITMAPINFO
Dim pixel1() As Byte
Dim r As Long
'建立位图信息结构(用于GetDIBits和SetDIBits)
With bmpinfo
.biBitCount = 24
.biHeight = nHeight
.biPlanes = 1
.biSize = 40
.biWidth = nWidth
.biSizeImage = ((nWidth * 3 + 3) And &H7FFFFFFC) * nHeight
End With
Dim SrcBitMap As Long
SrcBitMap = GetCurrentObject(hSrcDC, OBJ_BITMAP) '取得位图
If SrcBitMap = 0 Then Exit Sub
ReDim pixel1(1 To ((nWidth * 3 + 3) And &H7FFFFFFC),1 to nHeight)
GetDIBits hSrcDC, SrcBitMap, 0, nHeight, pixel1(1,1), bmpinfo, 0 fooAdjustBrightness pixel1(1,1), iValue, nWidth, nHeight, ((nWidth * 3 + 3) And &H7FFFFFFC) * nHeight
SetDIBits hSrcDC, SrcBitMap, 0, nHeight, pixel1(1,1), bmpinfo, 0
其中这个pixel1()的数组无论是一维还是二维都可以,这样就方便了我对图形数据的直接操作(无论是逐点修改还是做一个滤波器处理都没问题),但是这种思路换到VC中好像就不行了??
偶在MSDN上搜索了微软的一些例子,可是看到的都是使用类似如下的调用:
GetDIBits(hDC, _hBmp, (UINT)0, (UINT)_bmpInfo.bmiHeader.biHeight, (LPVOID)_buf, &_bmpInfo, DIB_RGB_COLORS);
其中_buf内就是图像数据的首地址。但是这样获取得数据对于使用卷积操作(哪怕只是3x3矩阵的操作)也是痛苦的很,因为需要在1维数组上不停的计算2维数组的对应位置。太容易出错了。所以部知道各位有没有好的办法来解决一下?或者说你们在使用卷积操作时究竟是怎样对数据进行处理的呢?
15 个解决方案
#1
顶
#2
定义一个二维指针,然后将_buf按一定的长度将地址赋予buf指针数组
BYTE** buf;
buf = (BYTE**)(new BYTE[nWidth*nHeight]);
buf[0] = _buf;
buf[1] = _buf + 1 * nWidth;
...
buf[nHeight - 1] = _buf + (nHeight - 1) * nWidth;
这样就可以直接用buf二维数组了
BYTE** buf;
buf = (BYTE**)(new BYTE[nWidth*nHeight]);
buf[0] = _buf;
buf[1] = _buf + 1 * nWidth;
...
buf[nHeight - 1] = _buf + (nHeight - 1) * nWidth;
这样就可以直接用buf二维数组了
#3
谢谢 Angus83(鱼)
顺便再请教一下其他的图像高手,一般都是怎么做这种程序呢?
顺便再请教一下其他的图像高手,一般都是怎么做这种程序呢?
#4
我们习惯用一维数组,也不麻烦。
#5
晕。。那么计算卷积呢?比如说5x5的卷积,中间的坐标换算岂不是很难写?
#6
混分
#7
ding
#8
用一维数组表达二维数组,就两行表达式,但一维数组有着高效的内存访问。
#9
unsigned char **pucImageData=NULL;
pucImageData = new unsigned char *[lWidth];
for ( i = 0; i < lWidth; i++)
{
pucImageData[i] = new unsigned char [lHeight];
}
for(j=0;j<lHeight;j++)
for(i=0;i<lWidth;i++)
{
pucImageData[i][j]=*(lpDIBBits + lLineBytes * (lHeight - 1 - j) + i);
}
for ( i =0; i<lHeight ; i++)
{
delete pucImageData[i];
}
delete pucImageData;
pucImageData = new unsigned char *[lWidth];
for ( i = 0; i < lWidth; i++)
{
pucImageData[i] = new unsigned char [lHeight];
}
for(j=0;j<lHeight;j++)
for(i=0;i<lWidth;i++)
{
pucImageData[i][j]=*(lpDIBBits + lLineBytes * (lHeight - 1 - j) + i);
}
for ( i =0; i<lHeight ; i++)
{
delete pucImageData[i];
}
delete pucImageData;
#10
用1维表示2维, 什么简单, 一般不会出错, 主要你还不习惯. 比如用一维数组表示一个M行N列的二维数组, 可以如下定义
BYTE buffer[M*N] ;
// 要引用第i行j列的数组元素, 就如下
... = buffer[ i * N + j ] ...
BYTE buffer[M*N] ;
// 要引用第i行j列的数组元素, 就如下
... = buffer[ i * N + j ] ...
#11
如果你实在不愿意写i*N+j, 那么可以用宏, 比如
#define buffer(i,j) buffer[(i)*N+(j)]
这样的写法已经跟VB的一样了吧.
#define buffer(i,j) buffer[(i)*N+(j)]
这样的写法已经跟VB的一样了吧.
#12
看来大家基本都还是用一维数组啊,稍微简便点可以把每行首地址先算出来存起来再调用
d = (int)((1.0-q) * ((1.0-p) * (*(data+((m+ys)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys)*m_nWidth+n+1+xs)*3)))+q * ((1.0-p) * (*(data+ ((m+ys+1)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys+1)*m_nWidth+n+1+xs)*3))));
这是双线性插值的一段,是不是很傻?
d = (int)((1.0-q) * ((1.0-p) * (*(data+((m+ys)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys)*m_nWidth+n+1+xs)*3)))+q * ((1.0-p) * (*(data+ ((m+ys+1)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys+1)*m_nWidth+n+1+xs)*3))));
这是双线性插值的一段,是不是很傻?
#13
关注
#14
一维数组只要控制好长度和宽度甚至高度值就可以很好的实现
#15
你可以把一维数组转换成2维得啊。。。。
同时,一维得算法也可以实现,,,同上。
同时,一维得算法也可以实现,,,同上。
#1
顶
#2
定义一个二维指针,然后将_buf按一定的长度将地址赋予buf指针数组
BYTE** buf;
buf = (BYTE**)(new BYTE[nWidth*nHeight]);
buf[0] = _buf;
buf[1] = _buf + 1 * nWidth;
...
buf[nHeight - 1] = _buf + (nHeight - 1) * nWidth;
这样就可以直接用buf二维数组了
BYTE** buf;
buf = (BYTE**)(new BYTE[nWidth*nHeight]);
buf[0] = _buf;
buf[1] = _buf + 1 * nWidth;
...
buf[nHeight - 1] = _buf + (nHeight - 1) * nWidth;
这样就可以直接用buf二维数组了
#3
谢谢 Angus83(鱼)
顺便再请教一下其他的图像高手,一般都是怎么做这种程序呢?
顺便再请教一下其他的图像高手,一般都是怎么做这种程序呢?
#4
我们习惯用一维数组,也不麻烦。
#5
晕。。那么计算卷积呢?比如说5x5的卷积,中间的坐标换算岂不是很难写?
#6
混分
#7
ding
#8
用一维数组表达二维数组,就两行表达式,但一维数组有着高效的内存访问。
#9
unsigned char **pucImageData=NULL;
pucImageData = new unsigned char *[lWidth];
for ( i = 0; i < lWidth; i++)
{
pucImageData[i] = new unsigned char [lHeight];
}
for(j=0;j<lHeight;j++)
for(i=0;i<lWidth;i++)
{
pucImageData[i][j]=*(lpDIBBits + lLineBytes * (lHeight - 1 - j) + i);
}
for ( i =0; i<lHeight ; i++)
{
delete pucImageData[i];
}
delete pucImageData;
pucImageData = new unsigned char *[lWidth];
for ( i = 0; i < lWidth; i++)
{
pucImageData[i] = new unsigned char [lHeight];
}
for(j=0;j<lHeight;j++)
for(i=0;i<lWidth;i++)
{
pucImageData[i][j]=*(lpDIBBits + lLineBytes * (lHeight - 1 - j) + i);
}
for ( i =0; i<lHeight ; i++)
{
delete pucImageData[i];
}
delete pucImageData;
#10
用1维表示2维, 什么简单, 一般不会出错, 主要你还不习惯. 比如用一维数组表示一个M行N列的二维数组, 可以如下定义
BYTE buffer[M*N] ;
// 要引用第i行j列的数组元素, 就如下
... = buffer[ i * N + j ] ...
BYTE buffer[M*N] ;
// 要引用第i行j列的数组元素, 就如下
... = buffer[ i * N + j ] ...
#11
如果你实在不愿意写i*N+j, 那么可以用宏, 比如
#define buffer(i,j) buffer[(i)*N+(j)]
这样的写法已经跟VB的一样了吧.
#define buffer(i,j) buffer[(i)*N+(j)]
这样的写法已经跟VB的一样了吧.
#12
看来大家基本都还是用一维数组啊,稍微简便点可以把每行首地址先算出来存起来再调用
d = (int)((1.0-q) * ((1.0-p) * (*(data+((m+ys)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys)*m_nWidth+n+1+xs)*3)))+q * ((1.0-p) * (*(data+ ((m+ys+1)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys+1)*m_nWidth+n+1+xs)*3))));
这是双线性插值的一段,是不是很傻?
d = (int)((1.0-q) * ((1.0-p) * (*(data+((m+ys)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys)*m_nWidth+n+1+xs)*3)))+q * ((1.0-p) * (*(data+ ((m+ys+1)*m_nWidth+n+xs)*3))+p * (*(data+((m+ys+1)*m_nWidth+n+1+xs)*3))));
这是双线性插值的一段,是不是很傻?
#13
关注
#14
一维数组只要控制好长度和宽度甚至高度值就可以很好的实现
#15
你可以把一维数组转换成2维得啊。。。。
同时,一维得算法也可以实现,,,同上。
同时,一维得算法也可以实现,,,同上。