如何在尽量少占用内存的情况下旋转图像文件

wuyapu 2004-08-12 08:21:43
将图像文件1旋转90度存入图像文件2,如何才能占用内存最小且速度不受太大影响。
...全文
212 点赞 收藏 12
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
wuyapu 2004-08-16
图像全部读入内存肯定不合适,有没有什么这折衷的方法,真是很郁闷阿,大家帮忙想个好办法
回复
wuyapu 2004-08-13
接着顶,大家还是没有回答到点子上,我要旋转的是图像文件,不希望一次性将图像全部读入内存
内存映射的问题是指针跳来跳去,速度好像很慢,
回复
huaboy408 2004-08-13
参看一下老大的帖子,看对你有没有帮助

面试问题: Rotate a bitmap by 90 degrees
http://community.csdn.net/Expert/topic/3254/3254627.xml?temp=4.619777E-03
回复
syy64 2004-08-13
用汇编编程。
回复
wanglh 2004-08-13
如果不想用太多内存,就从原图像中一个个像素的读出数据,计算目的图像中这个像素写入的位置,然后再写入文件。不过这样的话在目的文件内移动文件指针太频繁,效率不高。
因为旋转90度的图像,原来相连的图像点转换后分散开了,所以用小内存的话,文件指针移动肯定比较频繁。分块读入的效果也不是太理想。
回复
Jimmy_Xia 2004-08-13
楼主是要把一幅图像(不能全部读入内存的),一点一点的读取出来,再旋转90度,然后保存到另外一个文件。这个好难啊,我是菜鸟,只能顶一个了。
回复
LanceX 2004-08-13
如果您有小型的DIB并且需要频繁地操作图素位,您可以使用SetDIBitsToDevice和StretchDIBits来显示它们。然而,对于大型的DIB,此技术会遇到显示效能的问题,尤其在8位视讯显示器上和Windows NT环境下。

您可以使用CreateDIBitmap和SetDIBits把DIB转化为DDB。现在,显示位图可以使用快速的BitBlt和StretchBlt函数来进行了。然而,您不能直接存取这些与设备无关的图素位。

CreateDIBSection是一个很好的折衷方案。在Windows NT下通过BitBlt和StretchBlt使用位图句柄比使用SetDIBitsToDevice和StretchDIBits(但没有DDB的缺陷)会得到更好的效能。您仍然可以存取DIB图素位。

摘自<Windows程序设计>
回复
lixiaosan 2004-08-12
用gdi+

http://www.yesky.com/SoftChannel/72342380468174848/20040301/1772782_1.shtml
回复
huanyun 2004-08-12
typedef struct tagXIMGDATA
{
int width;
int height;
void * pScan0; // pointer to first scanline
int bpp; // bits per pixel
int stride; // distance between scanlines
} XIMGDATA;

void FreeImg(XIMGDATA& ImgDst)
{
if(ImgDst.pScan0 != NULL)
{
delete [] ImgDst.pScan0;
ImgDst.pScan0 = NULL;
ImgDst.width = 0;
ImgDst.height = 0;
ImgDst.bpp = 0;
ImgDst.stride = 0;
}
}

int RotateImg(XIMGDATA& ImgDst,const XIMGDATA& ImgSrc)
{
int nRet = -1;
FreeImg(ImgDst);

int nWidthS = ImgSrc.width;
int nHeightS = ImgSrc.height;
int nWidthD = nHeightS;
int nHeightD = nWidthS;
int nBitCount = ImgSrc.bpp;
int nRowLenSrc = ImgSrc.stride;
BYTE* pSrc = static_cast<BYTE*>(ImgSrc.pScan0);
if (nWidthS < 1 || nHeightS < 1
|| nWidthS > 10000 || nHeightS > 10000
|| nBitCount < 1 || nBitCount > 64
|| nRowLenSrc < 0 || pSrc == NULL)
return nRet;

int nRowLenDst = nWidthD * nBitCount / 8;
if (nBitCount == 1 && nWidthD % 8) ++nRowLenDst;
nRowLenDst = ((nRowLenDst + 3) & ~3);

BYTE *pDst = new BYTE[nHeightD*nRowLenDst];
if(pDst == NULL)
{
FreeImg(ImgDst);
return nRet;
}
memset(pDst, 0, nHeightD*nRowLenDst);
ImgDst.pScan0 = static_cast<void*>(pDst);
ImgDst.width = nWidthD;
ImgDst.height = nHeightD;
ImgDst.bpp = nBitCount;
ImgDst.stride = nRowLenDst;

int i,x,y,nPosS=0,nPosD=0;
int nPixelByte = ImgDst.bpp>>3;
BYTE bMaskD,bMaskS;
switch(nBitCount)
{
case 1:
for(y=0;y<nHeightD;++y)
{
nPosD = nRowLenDst*y;
nPosS = y>>3;
bMaskD = static_cast<BYTE>( 0x80 );
bMaskS = static_cast<BYTE>( 0x80 >> (y % 3) );
x = 0;
while(x < nWidthD)
{
if(pSrc[nPosS] & bMaskS)
{
pDst[nPosD] |= bMaskD;
}
++x;
bMaskD >>=1;
nPosS += nRowLenSrc;
if(bMaskD == 0)
{
bMaskD=0x80;
++nPosD;
}
}
for(x=0;;++x)
{
pDst[nPosD] = pSrc[nPosS];
nPosD += nPixelByte;
nPosS += nRowLenSrc;
}
}
nRet = 0;
break;
case 8:
case 16:
case 24:
case 32:
for(y=0;y<nHeightD;++y)
{
nPosD = nRowLenDst*y;
nPosS = y*nPixelByte;
for(x=0;x<nWidthD;++x)
{
for(i=0;i<nPixelByte;++i)
{
pDst[nPosD+i] = pSrc[nPosS+i];
}
nPosD += nPixelByte;
nPosS += nRowLenSrc;
}
}
nRet = 0;
break;
default:
break;
}
return nRet;
}
回复
s6283 2004-08-12
内存映射方式打开和保存文件
回复
wuyapu 2004-08-12
只旋转90度,这样不需要考虑插值。
文件比较大,如果文件小的话,我就直接全部读入内存了。
另外,我不需要显示
回复
酒红绿叶 2004-08-12
首先,图像不能太大,,太大速度会很慢。

另外,想提高速度,要优化算法,不使用差值算法。。
提高显示速度,可以用双缓存来解决!
回复
发帖
图形处理/算法
创建于2007-09-28

1.9w+

社区成员

VC/MFC 图形处理/算法
申请成为版主
帖子事件
创建了帖子
2004-08-12 08:21
社区公告
暂无公告