这段代码是在vc 2003环境下缩放图像,但是缩放出现异常,找不到原因。请各位高手给指点指点。
int pixel_width = 4;
void CImgProcessDlg::OnLoadImg()
{
m_MyImage.Load(_T("F:\\54321.jpg")); DWORD imageWidth = m_MyImage.GetWidth(); //获得图像宽度(像素单位)
DWORD imageHeight = m_MyImage.GetHeight(); //获得图像高度(像素单位)
DWORD pitch = m_MyImage.GetPitch(); //获得图像宽度(以Byte为单位)
BYTE* lpBits = (BYTE*)m_MyImage.GetBits(); //获得图像数据地址 BYTE *lpDIBBits = new BYTE[imageHeight*imageWidth*pixel_width];
memset( lpDIBBits, 0, imageHeight*imageWidth*pixel_width);
//复制图像数据到lpDIBBits;
if(m_MyImage.GetBPP()==24)
{
for (int i = 0; i < imageHeight; i++)
{
for (int j = 0; j < imageWidth; j++)
{
BYTE r, g, b, a;
COLORREF pixel = m_MyImage.GetPixel( j, i); r = GetRValue(pixel); // 红
g = GetGValue(pixel); // 绿
b = GetBValue(pixel); // 蓝
a = 0; // 透明色 *lpDIBBits++ = r; // 红
*lpDIBBits++ = g; // 绿
*lpDIBBits++ = b; // 蓝
*lpDIBBits++ = a; // 透明色
}
}
}
else
{
::MessageBox(NULL,_T("只能打开8或24位图像!"),NULL,MB_ICONSTOP);
return;
} DWORD iDestWidth = 600;
DWORD iDestHeight = 800;
byte *dst = new BYTE[iDestWidth*iDestHeight*pixel_width]; // 转换图像
zoom( dst, lpDIBBits, imageWidth, imageHeight, iDestWidth, iDestHeight); m_DestImg.CreateEx( iDestWidth, iDestHeight, 24, BI_BITFIELDS);
COLORREF pixel;
for( DWORD i = 0; i < iDestHeight; i++)
{
for( DWORD j = 0; j < iDestWidth; j++)
{
pixel = RGB( *dst++, *dst++, *dst++);
dst++; // 透明色
m_DestImg.SetPixel( i, j, pixel);
}
} m_DestImg.Save( _T("F:\\liuwei.jpg")); return;
}/*
dst : 目标缓冲区
src : 来源缓冲区
sw : 来源图像宽度
sh : 来源图像高度
dw : 目标图像宽度
dh : 目标图像高度
*/
void CImgProcessDlg::zoom(byte *dst, byte *src, long sw, long sh, long dw,long dh)
{
assert(dst != 0);
assert(src != 0);
assert(sw > 0 && sh > 0);
assert(dw > 0 && dh > 0); float scalex = static_cast<float>(sw) / static_cast<float>(dw);
float scaley = static_cast<float>(sh) / static_cast<float>(dh); long width_bytes = static_cast<long>(sw) * pixel_width; long *pbyDst = reinterpret_cast<long*>(dst); for(long i = 0; i < dh; i++)
{
float inverse_y = i * scaley;
long yy = static_cast<long>(inverse_y);
byte *pbySrc = src + yy * width_bytes; for(long j = 0; j < dw; j++)
{
float inverse_x = j * scalex; long xx = static_cast<long>(inverse_x);
long* pbyCurrent = reinterpret_cast<long*>(pbySrc + pixel_width * xx); *pbyDst = *pbyCurrent; pbyDst++;
}
}
}
int pixel_width = 4;
void CImgProcessDlg::OnLoadImg()
{
m_MyImage.Load(_T("F:\\54321.jpg")); DWORD imageWidth = m_MyImage.GetWidth(); //获得图像宽度(像素单位)
DWORD imageHeight = m_MyImage.GetHeight(); //获得图像高度(像素单位)
DWORD pitch = m_MyImage.GetPitch(); //获得图像宽度(以Byte为单位)
BYTE* lpBits = (BYTE*)m_MyImage.GetBits(); //获得图像数据地址 BYTE *lpDIBBits = new BYTE[imageHeight*imageWidth*pixel_width];
memset( lpDIBBits, 0, imageHeight*imageWidth*pixel_width);
//复制图像数据到lpDIBBits;
if(m_MyImage.GetBPP()==24)
{
for (int i = 0; i < imageHeight; i++)
{
for (int j = 0; j < imageWidth; j++)
{
BYTE r, g, b, a;
COLORREF pixel = m_MyImage.GetPixel( j, i); r = GetRValue(pixel); // 红
g = GetGValue(pixel); // 绿
b = GetBValue(pixel); // 蓝
a = 0; // 透明色 *lpDIBBits++ = r; // 红
*lpDIBBits++ = g; // 绿
*lpDIBBits++ = b; // 蓝
*lpDIBBits++ = a; // 透明色
}
}
}
else
{
::MessageBox(NULL,_T("只能打开8或24位图像!"),NULL,MB_ICONSTOP);
return;
} DWORD iDestWidth = 600;
DWORD iDestHeight = 800;
byte *dst = new BYTE[iDestWidth*iDestHeight*pixel_width]; // 转换图像
zoom( dst, lpDIBBits, imageWidth, imageHeight, iDestWidth, iDestHeight); m_DestImg.CreateEx( iDestWidth, iDestHeight, 24, BI_BITFIELDS);
COLORREF pixel;
for( DWORD i = 0; i < iDestHeight; i++)
{
for( DWORD j = 0; j < iDestWidth; j++)
{
pixel = RGB( *dst++, *dst++, *dst++);
dst++; // 透明色
m_DestImg.SetPixel( i, j, pixel);
}
} m_DestImg.Save( _T("F:\\liuwei.jpg")); return;
}/*
dst : 目标缓冲区
src : 来源缓冲区
sw : 来源图像宽度
sh : 来源图像高度
dw : 目标图像宽度
dh : 目标图像高度
*/
void CImgProcessDlg::zoom(byte *dst, byte *src, long sw, long sh, long dw,long dh)
{
assert(dst != 0);
assert(src != 0);
assert(sw > 0 && sh > 0);
assert(dw > 0 && dh > 0); float scalex = static_cast<float>(sw) / static_cast<float>(dw);
float scaley = static_cast<float>(sh) / static_cast<float>(dh); long width_bytes = static_cast<long>(sw) * pixel_width; long *pbyDst = reinterpret_cast<long*>(dst); for(long i = 0; i < dh; i++)
{
float inverse_y = i * scaley;
long yy = static_cast<long>(inverse_y);
byte *pbySrc = src + yy * width_bytes; for(long j = 0; j < dw; j++)
{
float inverse_x = j * scalex; long xx = static_cast<long>(inverse_x);
long* pbyCurrent = reinterpret_cast<long*>(pbySrc + pixel_width * xx); *pbyDst = *pbyCurrent; pbyDst++;
}
}
}
解决方案 »
- mfc里如何设置static text文字中其中一部分文字的颜色啊
- 在线等!!!单文档的视图,可以通过Tab控件switch
- vc6.0——CreateDispatch("Word.Application")出错
- vc和DELPHI的专家请帮忙,VC调用DELPHI编写的动态连接库的问题,兄弟的分不多了,请体谅
- 在VC++中如何模拟键盘输入参数到一个DOS程序中,使得DOS程序可以自动运行计算,不必手工输入参数。
- 零长度数组问题
- 急!急!急!用vc如何把数据库中的jpeg文件读出并在视图中显示出来?
- 请问如何将对话框里的对象变量的改变传递到view里面的变量
- 自定义消息
- 如何定制ActiveX控件的界面和图标
- 关于 数据类型转换的问题
- debug下多线程出错,release正常
g = GetGValue(pixel); // 绿
b = GetBValue(pixel); // 蓝
a = 0; // 透明色 *lpDIBBits++ = r; // 红
*lpDIBBits++ = g; // 绿
*lpDIBBits++ = b; // 蓝
*lpDIBBits++ = a; // 透明色 这个不如一开始就申明UINT* lpDIBBits
直接就*lpDIBBits++ = m_MyImage.GetPixel( j, i); byte *dst = new BYTE[iDestWidth*iDestHeight*pixel_width];
这句很可能有问题。用heapalloc分配内存试试吧。后面的算法就有点看不懂了,不知道缩放怎么做的,应该用插值吧,有个D3DXColorLerp方法,你试试。
{
assert(dst != 0);
assert(src != 0);
assert(sw > 0 && sh > 0);
assert(dw > 0 && dh > 0); float scalex = static_cast <float>(sw) / static_cast <float>(dw); // x缩放因子
float scaley = static_cast <float>(sh) / static_cast <float>(dh); // y缩放因子long width_bytes = static_cast <long>(sw) * pixel_width; // 源图像每行字节数long *pbyDst = reinterpret_cast <long*>(dst); // 将dst看作long* (每个*dst相当于4bytes), 此处限制仅用于32bits的图像缩放,不过可以提高缩放速度!for(long i = 0; i < dh; i++)
{
float inverse_y = i * scaley; // 计算dst中的每一行在源图像中的位置
long yy = static_cast <long>(inverse_y); // 取整
byte *pbySrc = src + yy * width_bytes; // 获取源图像中此行数据for(long j = 0; j < dw; j++)
{
float inverse_x = j * scalex; // 计算dst中的每一列在源图像中的位置long xx = static_cast <long>(inverse_x); // 取整
long* pbyCurrent = reinterpret_cast <long*>(pbySrc + pixel_width * xx); // 获取源图像中对应点的像素值 (long -〉4bits ARGB)*pbyDst = *pbyCurrent; // 赋值pbyDst++; // dst中下一个点
}
}
}注意其中的
long* pbyCurrent = reinterpret_cast <long*>(pbySrc + pixel_width * xx); // 获取源图像中对应点的像素值 (long -〉4bits ARGB)
确认你所写的
*lpDIBBits++ = r; // 红
*lpDIBBits++ = g; // 绿
*lpDIBBits++ = b; // 蓝
*lpDIBBits++ = a; // 透明色
顺序是否正确
我记得好像是ARGB的顺序,也就是
*lpDIBBits++ = b; // 蓝
*lpDIBBits++ = g; // 绿
*lpDIBBits++ = r; // 红
*lpDIBBits++ = a; // 透明色
楼主试试 , 或者我记错了, 多试试
缩放后的结果是 黑白色 ……
看来换得继续 发帖, 各位帮指点指点
void CImgProcessDlg::OnLoadImg()
{
CImage m_MyImage;
m_MyImage.Load(_T("F:\\54321.jpg")); DWORD imageWidth = m_MyImage.GetWidth(); //获得图像宽度(像素单位)
DWORD imageHeight = m_MyImage.GetHeight(); //获得图像高度(像素单位)
DWORD pitch = m_MyImage.GetPitch(); //获得图像宽度(以Byte为单位)
BYTE* lpBits = (BYTE*)m_MyImage.GetBits(); //获得图像数据地址 BYTE *lpDIBBits = new BYTE[imageHeight*imageWidth*pixel_width];
memset( lpDIBBits, 0, imageHeight*imageWidth*pixel_width); int iPos = 0;
//复制图像数据到lpDIBBits;
if(m_MyImage.GetBPP()==24)
{
for (int i = 0; i < imageHeight; i++)
{
for (int j = 0; j < imageWidth; j++)
{
BYTE r, g, b, a;
COLORREF pixel = m_MyImage.GetPixel( j, i); r = GetRValue(pixel); // 红
g = GetGValue(pixel); // 绿
b = GetBValue(pixel); // 蓝
a = 0; // 透明色 lpDIBBits[iPos] = pixel;
lpDIBBits[iPos + 1] = g;
lpDIBBits[iPos + 2] = b;
lpDIBBits[iPos + 3] = a;
iPos += 4;
}
}
}
else
{
::MessageBox(NULL,_T("只能打开8或24位图像!"),NULL,MB_ICONSTOP);
return;
} int iDestWidth = 1024;
int iDestHeight = 768;
byte *dst = new BYTE[iDestWidth*iDestHeight*pixel_width]; // 转换图像
zoom( dst, lpDIBBits, imageWidth, imageHeight, iDestWidth, iDestHeight); CImage m_DestImg;
DWORD adwBitmasks[3] = { 0x00000000, 0x00000000, 0x00000000};
m_DestImg.CreateEx( iDestWidth, iDestHeight, 24, 0);//, adwBitmasks, 0);
COLORREF pixel;
for( int m = 0; m < iDestHeight; m++)
{
for( int n = 0; n < iDestWidth; n++)
{
pixel = RGB( *dst++, *dst++, *dst++);
dst++; // 透明色
m_DestImg.SetPixel( n, m, pixel);
}
} m_DestImg.Save( _T("F:\\TestJpg.jpg")); return;
}/*dst : 目标缓冲区src : 来源缓冲区sw : 来源图像宽度sh : 来源图像高度dw : 目标图像宽度dh : 目标图像高度*/
void CImgProcessDlg::zoom(byte *dst, byte *src, long sw, long sh, long dw,long dh)
{
assert(dst != 0);
assert(src != 0);
assert(sw > 0 && sh > 0);
assert(dw > 0 && dh > 0);
// x缩放因子
float scalex = static_cast <float>(sw) / static_cast <float>(dw);
// y缩放因子
float scaley = static_cast <float>(sh) / static_cast <float>(dh);
// 源图像每行字节数
long width_bytes = static_cast <long>(sw) * pixel_width;
// 将dst看作long* (每个*dst相当于4bytes), 此处限制仅用于32bits的图像缩放,不过可以提高缩放速度!
long *pbyDst = reinterpret_cast <long*>(dst); for(long i = 0; i < dh; i++)
{
// 计算dst中的每一行在源图像中的位置
float inverse_y = i * scaley;
// 取整
long yy = static_cast <long>(inverse_y);
// 获取源图像中此行数据
byte *pbySrc = src + yy * width_bytes; for(long j = 0; j < dw; j++)
{
// 计算dst中的每一列在源图像中的位置
float inverse_x = j * scalex;
// 取整
long xx = static_cast <long>(inverse_x);
// 获取源图像中对应点的像素值 (long -〉4bits ARGB)
long* pbyCurrent = reinterpret_cast <long*>(pbySrc + pixel_width * xx);
// 赋值
*pbyDst = *pbyCurrent;
// dst中下一个点
pbyDst++;
}
}
}
void CImgProcessDlg::OnLoadImg()
{
CImage m_MyImage;
m_MyImage.Load(_T("F:\\54321.jpg")); DWORD imageWidth = m_MyImage.GetWidth(); //获得图像宽度(像素单位)
DWORD imageHeight = m_MyImage.GetHeight(); //获得图像高度(像素单位)
DWORD pitch = m_MyImage.GetPitch(); //获得图像宽度(以Byte为单位)
BYTE* lpBits = (BYTE*)m_MyImage.GetBits(); //获得图像数据地址 BYTE *lpDIBBits = new BYTE[imageHeight*imageWidth*pixel_width];
memset( lpDIBBits, 0, imageHeight*imageWidth*pixel_width); int iPos = 0;
//复制图像数据到lpDIBBits;
if(m_MyImage.GetBPP()==24)
{
for (int i = 0; i < imageHeight; i++)
{
for (int j = 0; j < imageWidth; j++)
{
BYTE r, g, b, a;
COLORREF pixel = m_MyImage.GetPixel( j, i); r = GetRValue(pixel); // 红
g = GetGValue(pixel); // 绿
b = GetBValue(pixel); // 蓝
a = 0; // 透明色 lpDIBBits[iPos] = b;
lpDIBBits[iPos + 1] = g;
lpDIBBits[iPos + 2] = r;
lpDIBBits[iPos + 3] = a;
iPos += 4;
}
}
}
else
{
::MessageBox(NULL,_T("只能打开8或24位图像!"),NULL,MB_ICONSTOP);
return;
} int iDestWidth = 1024;
int iDestHeight = 768;
byte *dst = new BYTE[iDestWidth*iDestHeight*pixel_width]; // 转换图像
zoom( dst, lpDIBBits, imageWidth, imageHeight, iDestWidth, iDestHeight); CImage m_DestImg;
DWORD adwBitmasks[3] = { 0x00000000, 0x00000000, 0x00000000};
m_DestImg.CreateEx( iDestWidth, iDestHeight, 24, 0);//, adwBitmasks, 0);
COLORREF pixel;
for( int m = 0; m < iDestHeight; m++)
{
for( int n = 0; n < iDestWidth; n++)
{
pixel = RGB( *dst++, *dst++, *dst++);
dst++; // 透明色
m_DestImg.SetPixel( n, m, pixel);
}
} m_DestImg.Save( _T("F:\\TestJpg1.jpg")); return;
}/*dst : 目标缓冲区src : 来源缓冲区sw : 来源图像宽度sh : 来源图像高度dw : 目标图像宽度dh : 目标图像高度*/
void CImgProcessDlg::zoom(byte *dst, byte *src, long sw, long sh, long dw,long dh)
{
assert(dst != 0);
assert(src != 0);
assert(sw > 0 && sh > 0);
assert(dw > 0 && dh > 0);
// x缩放因子
float scalex = static_cast <float>(sw) / static_cast <float>(dw);
// y缩放因子
float scaley = static_cast <float>(sh) / static_cast <float>(dh);
// 源图像每行字节数
long width_bytes = static_cast <long>(sw) * pixel_width;
// 将dst看作long* (每个*dst相当于4bytes), 此处限制仅用于32bits的图像缩放,不过可以提高缩放速度!
long *pbyDst = reinterpret_cast <long*>(dst); for(long i = 0; i < dh; i++)
{
// 计算dst中的每一行在源图像中的位置
float inverse_y = i * scaley;
// 取整
long yy = static_cast <long>(inverse_y);
// 获取源图像中此行数据
byte *pbySrc = src + yy * width_bytes; for(long j = 0; j < dw; j++)
{
// 计算dst中的每一列在源图像中的位置
float inverse_x = j * scalex;
// 取整
long xx = static_cast <long>(inverse_x);
// 获取源图像中对应点的像素值 (long -〉4bits ARGB)
long* pbyCurrent = reinterpret_cast <long*>(pbySrc + pixel_width * xx);
// 赋值
*pbyDst = *pbyCurrent;
// dst中下一个点
pbyDst++;
}
}
}
for( int m = 0; m < iDestHeight; m++)
{
for( int n = 0; n < iDestWidth; n++)
{
pixel = RGB( *dst++, *dst++, *dst++);
dst++; // 透明色
m_DestImg.SetPixel( n, m, pixel);
}
} 不明白为什么喜欢用这种表达式 —— pixel = RGB( *dst++, *dst++, *dst++);
个人很不喜欢,因为很容易出错,譬如 pixel = RGB( *++dst, *++dst, *++dst); 之类
用在这里都是不正确的
上述两个表达式,楼主可以单步试试结果正确应为:
COLORREF pixel;
for( int m = 0; m < iDestHeight; m++)
{
for( int n = 0; n < iDestWidth; n++)
{
pixel = RGB( *(dst+2), *(dst+1), *dst);
dst+=4; // 透明色
m_DestImg.SetPixel( n, m, pixel);
}
}