用GDI+对图象旋转和缩小后,发现图象有失真的现象! 最近有个项目,把一JPEG图片旋转 后要缩小到一寸的大小.用GDI+进行上述操作后发现图片有失真的现象, 可客户要拿图片冲洗照片.所以解决这个问题一直很头疼. 听说有算法可避免上述现象, 最好还是用GDI+ ,能给出VC++的代码最好. 谢谢了 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 #pragma once #ifndef __ENHANCED_SHRINK_HPP__#define __ENHANCED_SHRINK_HPP__//shrink using GDI+struct GdiplusManager{ GdiplusManager(); ~GdiplusManager(); bool gdiplus_ok; ULONG gdiplusToken; };int GDIPlus_StretchDIBits( HDC hdc, // handle to DC int XDest, // x-coord of destination upper-left corner int YDest, // y-coord of destination upper-left corner int nDestWidth, // width of destination rectangle int nDestHeight, // height of destination rectangle int XSrc, // x-coord of source upper-left corner int YSrc, // y-coord of source upper-left corner int nSrcWidth, // width of source rectangle int nSrcHeight, // height of source rectangle CONST VOID *lpBits, // bitmap bits CONST BITMAPINFO *lpBitsInfo, // bitmap data UINT iUsage, // usage options DWORD dwRop // raster operation code);#endif #include "StdAfx.h"//need to have D:\Apps\Microsoft SDK\Include preceeds VC standard headers #include "enhanced_shrink.h"#include <windows.h>#include <Objbase.h>#include <Gdiplus.h>#include <GdiPlusEnums.h>#pragma comment(lib,"gdiplus")#pragma comment(lib, "delayimp.lib")#pragma comment(linker, "/VERBOSE:LIB")#include <memory>#include <comutil.h>#pragma comment(lib,"comsupp.lib")using namespace Gdiplus;GdiplusManager::GdiplusManager(){ Gdiplus::GdiplusStartupInput gdiplusStartupInput; Gdiplus::Status gdiplus_status; gdiplus_status = Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); if(Gdiplus::Ok == gdiplus_status) gdiplus_ok = true; }GdiplusManager::~GdiplusManager(){ if(gdiplus_ok) Gdiplus::GdiplusShutdown(gdiplusToken);}GdiplusManager global_gdi_object;//must be global objectint GDIPlus_StretchDIBits( HDC hdc, // handle to DC int XDest, // x-coord of destination upper-left corner int YDest, // y-coord of destination upper-left corner int nDestWidth, // width of destination rectangle int nDestHeight, // height of destination rectangle int XSrc, // x-coord of source upper-left corner int YSrc, // y-coord of source upper-left corner int nSrcWidth, // width of source rectangle int nSrcHeight, // height of source rectangle CONST VOID *lpBits, // bitmap bits CONST BITMAPINFO *lpBitsInfo, // bitmap data UINT iUsage, // usage options DWORD dwRop // raster operation code){ if(false == global_gdi_object.gdiplus_ok || nDestHeight >= nSrcHeight || nDestWidth >= nSrcWidth) { int nret = StretchDIBits(hdc,XDest,YDest,nDestWidth,nDestHeight, XSrc,YSrc,nSrcWidth, nSrcHeight,lpBits,lpBitsInfo,iUsage,dwRop); return nret; } try { typedef std::auto_ptr<Bitmap> PtrBitmap; PtrBitmap imgPhoto(Bitmap::FromBITMAPINFO(lpBitsInfo,(void*)lpBits)) ; Bitmap bmptmp(nDestWidth, nDestHeight, PixelFormat24bppRGB); Bitmap* bmPhoto = &bmptmp; bmPhoto->SetResolution(imgPhoto->GetHorizontalResolution(), imgPhoto->GetVerticalResolution()); std::auto_ptr<Graphics> grPhoto (Graphics::FromImage(bmPhoto)); grPhoto->Clear(Color.White); grPhoto->SetInterpolationMode( InterpolationModeHighQualityBilinear); Point destPoints[3]; destPoints[0].X = XDest; //left top destPoints[0].Y = YDest; destPoints[1].X = XDest + nDestWidth; //right top destPoints[1].Y = YDest; destPoints[2].X = XDest; //left bottom destPoints[2].Y = YDest + nDestHeight; grPhoto->DrawImage(imgPhoto.get(),(const Point*)destPoints,3,XSrc, YSrc,nSrcWidth,nSrcHeight,UnitPixel, NULL,NULL,NULL); HBITMAP hbmp = NULL; Color background; bmPhoto->GetHBITMAP(background,&hbmp); BITMAP bm; GetObject(hbmp,sizeof(bm),&bm); HDC dcmem; dcmem = CreateCompatibleDC(hdc); ::SelectObject(dcmem,hbmp); ::BitBlt(hdc,XDest,YDest,nDestWidth,nDestHeight,dcmem,XSrc,YSrc,SRCCOPY); } catch(...) { int nret = StretchDIBits(hdc,XDest,YDest,nDestWidth,nDestHeight, XSrc,YSrc,nSrcWidth, nSrcHeight,lpBits,lpBitsInfo,iUsage,dwRop); return nret; } return 0;} to :masterz(www.fruitfruit.com) grPhoto->SetInterpolationMode( InterpolationModeHighQualityBilinear);用GDI+的这个方法不行么? 怎么如此复杂!!! up====CSDN 小助手 V2.5 2005年11月05日发布====CSDN小助手是一款脱离浏览器也可以访问Csdn论坛的软件界面:http://blog.csdn.net/Qqwwee_Com/archive/2005/11/05/523395.aspx下载:http://szlawbook.com/csdnv2 USB设备建立通路后,如何正常传输数据 对话框拉左/上边改变大小时产生的画面的抖动问题 一个圆弧的象限关系 帮我解释下数学意思 完成端口 发送文件问题 DBGrid问题 SQL Server2000中,我要用建一些对用户不可见的表,表名是什么不重要,只要唯一就行。用NEWID()? 大侠们,小弟有问题要问,小弟在线等. 帮忙看看一个小问题! 如何从资源文件中读出bitmap,并在picture control 中显示? 如何对button附上图片或图标? 如何使程序的文件在文件夹选择缩略图方式时可以显示出一幅图片? 如何不失真的缩小图片???
#ifndef __ENHANCED_SHRINK_HPP__
#define __ENHANCED_SHRINK_HPP__
//shrink using GDI+
struct GdiplusManager
{
GdiplusManager();
~GdiplusManager();
bool gdiplus_ok;
ULONG gdiplusToken;
};int GDIPlus_StretchDIBits(
HDC hdc, // handle to DC
int XDest, // x-coord of destination upper-left corner
int YDest, // y-coord of destination upper-left corner
int nDestWidth, // width of destination rectangle
int nDestHeight, // height of destination rectangle
int XSrc, // x-coord of source upper-left corner
int YSrc, // y-coord of source upper-left corner
int nSrcWidth, // width of source rectangle
int nSrcHeight, // height of source rectangle
CONST VOID *lpBits, // bitmap bits
CONST BITMAPINFO *lpBitsInfo, // bitmap data
UINT iUsage, // usage options
DWORD dwRop // raster operation code
);#endif
//need to have D:\Apps\Microsoft SDK\Include preceeds VC standard headers
#include "enhanced_shrink.h"
#include <windows.h>
#include <Objbase.h>
#include <Gdiplus.h>
#include <GdiPlusEnums.h>
#pragma comment(lib,"gdiplus")
#pragma comment(lib, "delayimp.lib")
#pragma comment(linker, "/VERBOSE:LIB")
#include <memory>
#include <comutil.h>
#pragma comment(lib,"comsupp.lib")
using namespace Gdiplus;
GdiplusManager::GdiplusManager()
{
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::Status gdiplus_status;
gdiplus_status = Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
if(Gdiplus::Ok == gdiplus_status)
gdiplus_ok = true;
}
GdiplusManager::~GdiplusManager()
{
if(gdiplus_ok)
Gdiplus::GdiplusShutdown(gdiplusToken);
}GdiplusManager global_gdi_object;//must be global objectint GDIPlus_StretchDIBits(
HDC hdc, // handle to DC
int XDest, // x-coord of destination upper-left corner
int YDest, // y-coord of destination upper-left corner
int nDestWidth, // width of destination rectangle
int nDestHeight, // height of destination rectangle
int XSrc, // x-coord of source upper-left corner
int YSrc, // y-coord of source upper-left corner
int nSrcWidth, // width of source rectangle
int nSrcHeight, // height of source rectangle
CONST VOID *lpBits, // bitmap bits
CONST BITMAPINFO *lpBitsInfo, // bitmap data
UINT iUsage, // usage options
DWORD dwRop // raster operation code
)
{
if(false == global_gdi_object.gdiplus_ok
|| nDestHeight >= nSrcHeight
|| nDestWidth >= nSrcWidth)
{
int nret = StretchDIBits(hdc,XDest,YDest,nDestWidth,nDestHeight,
XSrc,YSrc,nSrcWidth,
nSrcHeight,lpBits,lpBitsInfo,iUsage,dwRop);
return nret;
}
try
{
typedef std::auto_ptr<Bitmap> PtrBitmap;
PtrBitmap imgPhoto(Bitmap::FromBITMAPINFO(lpBitsInfo,(void*)lpBits)) ;
Bitmap bmptmp(nDestWidth, nDestHeight, PixelFormat24bppRGB);
Bitmap* bmPhoto = &bmptmp;
bmPhoto->SetResolution(imgPhoto->GetHorizontalResolution(),
imgPhoto->GetVerticalResolution());
std::auto_ptr<Graphics> grPhoto (Graphics::FromImage(bmPhoto));
grPhoto->Clear(Color.White);
grPhoto->SetInterpolationMode( InterpolationModeHighQualityBilinear);
Point destPoints[3];
destPoints[0].X = XDest; //left top
destPoints[0].Y = YDest;
destPoints[1].X = XDest + nDestWidth; //right top
destPoints[1].Y = YDest;
destPoints[2].X = XDest; //left bottom
destPoints[2].Y = YDest + nDestHeight;
grPhoto->DrawImage(imgPhoto.get(),(const Point*)destPoints,3,XSrc,
YSrc,nSrcWidth,nSrcHeight,UnitPixel,
NULL,NULL,NULL);
HBITMAP hbmp = NULL;
Color background;
bmPhoto->GetHBITMAP(background,&hbmp);
BITMAP bm;
GetObject(hbmp,sizeof(bm),&bm);
HDC dcmem;
dcmem = CreateCompatibleDC(hdc);
::SelectObject(dcmem,hbmp);
::BitBlt(hdc,XDest,YDest,nDestWidth,nDestHeight,dcmem,XSrc,YSrc,SRCCOPY);
}
catch(...)
{
int nret = StretchDIBits(hdc,XDest,YDest,nDestWidth,nDestHeight,
XSrc,YSrc,nSrcWidth,
nSrcHeight,lpBits,lpBitsInfo,iUsage,dwRop);
return nret;
}
return 0;
}
grPhoto->SetInterpolationMode( InterpolationModeHighQualityBilinear);用GDI+的这个方法不行么? 怎么如此复杂!!!
CSDN小助手是一款脱离浏览器也可以访问Csdn论坛的软件
界面:http://blog.csdn.net/Qqwwee_Com/archive/2005/11/05/523395.aspx
下载:http://szlawbook.com/csdnv2