关于用GDI+以及CXImage显示各种类型图片后不能局部放大的问题

时间:2021-07-21 17:39:19
首先说下局部放大的含义:
局部放大是指,由于某些控件大小与图片实际大小不符而导致显示不清楚,可以对图像实现局部放大显示,不是单纯的放大屏幕。

开始没用GDI+以及CXImage,直接用StretchBlt函数就可以实现效果很好的局部放大。比如两个Timage,将Image1图片位置 100,100开始,大小为200,200的区域拉伸显示到Image2上
StretchBlt(Image2->Canvas->Handle,0,0,Image2->Width,Image2->Height,Image1->Canvas->Handle,100,100,200,200,0xCC0020);
但这样有个问题,目前的Timage只能支持BMP,JPG等,不能支持Tiff,Gif,Png等格式.

使用GDI+以及CXImage后,由于是直接通过GDI+的DrawImage方法或者CXImage的Draw方法在TImage1->Canavs->Handle上画出图像,可以支持多种格式,
但再调用StretchBlt函数后,不再能实现放大,仅仅是将显示出的图像原封不动拷贝至另外一个显示区域,多出的地方为空白,请问大家如何实现上述功能?

9 个解决方案

#1


没有哪位大虾知道嘛?指导一下!

#2


DrawImage不就实现放大了么?就不用StretchBlt了。另外,看看代码。

#3


Image img( WideString("c:\\test.tif "));
//把原图象在Image1中显示
RealWidth = img.GetWidth();
RealHeight = img.GetHeight();
Gdiplus::Graphics   graph(Image1->Canvas->Handle);
graph.DrawImage(&img,0,0,Image1->Width,Image1->Height);
graph.ReleaseHDC(Image1->Canvas->Handle);

//鼠标移动将Image1的某区域放大至Image2上
//比如 现在要求放大原图象 100,100开始,大小为200,200的区域放大显示在Image2中

void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
      Image img( WideString("c:\\test.tif "));
  Image2->Left = X + 100;
  Image2->Top = Y + 100;
  float Xpix = (float)RealWidth/Image1->Width;
  float Ypix = (float)RealHeight/Image1->Height;

  //::StretchBlt(Image2->Canvas->Handle,0,0,Image2->Width,Image2->Height,Image1->Canvas->Handle,X,Y,200,100,0xCC0020);
  Gdiplus::Graphics   graph2(Image2->Canvas->Handle);
  graph2.DrawImage(&img,X,Y,200,200);
  graph2.ReleaseHDC(Image1->Canvas->Handle);
}

实现不了这个想过效果!

#4


应可以通过drawImage(&image,destRect,roiRect,....);你可以查阅这个重载函数 ,好好看看。

#5



//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <algorithm>
using std::min;
using std::max;
#include <gdiplus.h>
using namespace Gdiplus;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

ULONG gdiplusToken;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
GdiplusShutdown(gdiplusToken);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Gdiplus::Bitmap GpBmp(WideString("msn1.gif"));
HBITMAP HBmp;
GpBmp.GetHBITMAP(0, &HBmp);
Image1->Picture->Bitmap->Handle = HBmp;
Gdiplus::Graphics g(Image2->Canvas->Handle);
// 放大,其效果比StretchBlt好些
g.DrawImage(&GpBmp, Gdiplus::Rect(0, 0, Image2->Width, Image2->Height),
10, 10, 100, 100, UnitPixel);
// 也可放大,效果不好
// ::StretchBlt(Image2->Canvas->Handle, 0, 0, Image2->Width, Image2->Height,
// Image1->Canvas->Handle, 10, 10, 100, 100, 0xCC0020);
}
//---------------------------------------------------------------------------

#6


怎么把BCB问题发到VC板块?

#7


引用楼主 vick 的帖子:
首先说下 局部放大的含义: 
局部放大是指,由于某些控件大小与图片实际大小不符而导致显示不清楚,可以对图像实现 局部放大显示,不是单纯的放大屏幕。 


没看懂,感觉你是概念在解释概念

#8


放大屏幕就比如放大镜,模糊的图片仍然是模糊的,可能就是没有进行任何插值算法填充放大的空白点。

图片局部放大,比如图片本身很大,显示界面很小,进行了缩放后,你选择其中某一块,那么放大出来的可以是原图或者进行了插值算法填充后的,效果很好

#9


用BCB和VC都可以,哪种能解决用哪种。
谢谢各位,结帐给分。

#1


没有哪位大虾知道嘛?指导一下!

#2


DrawImage不就实现放大了么?就不用StretchBlt了。另外,看看代码。

#3


Image img( WideString("c:\\test.tif "));
//把原图象在Image1中显示
RealWidth = img.GetWidth();
RealHeight = img.GetHeight();
Gdiplus::Graphics   graph(Image1->Canvas->Handle);
graph.DrawImage(&img,0,0,Image1->Width,Image1->Height);
graph.ReleaseHDC(Image1->Canvas->Handle);

//鼠标移动将Image1的某区域放大至Image2上
//比如 现在要求放大原图象 100,100开始,大小为200,200的区域放大显示在Image2中

void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
      Image img( WideString("c:\\test.tif "));
  Image2->Left = X + 100;
  Image2->Top = Y + 100;
  float Xpix = (float)RealWidth/Image1->Width;
  float Ypix = (float)RealHeight/Image1->Height;

  //::StretchBlt(Image2->Canvas->Handle,0,0,Image2->Width,Image2->Height,Image1->Canvas->Handle,X,Y,200,100,0xCC0020);
  Gdiplus::Graphics   graph2(Image2->Canvas->Handle);
  graph2.DrawImage(&img,X,Y,200,200);
  graph2.ReleaseHDC(Image1->Canvas->Handle);
}

实现不了这个想过效果!

#4


应可以通过drawImage(&image,destRect,roiRect,....);你可以查阅这个重载函数 ,好好看看。

#5



//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <algorithm>
using std::min;
using std::max;
#include <gdiplus.h>
using namespace Gdiplus;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

ULONG gdiplusToken;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
GdiplusShutdown(gdiplusToken);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Gdiplus::Bitmap GpBmp(WideString("msn1.gif"));
HBITMAP HBmp;
GpBmp.GetHBITMAP(0, &HBmp);
Image1->Picture->Bitmap->Handle = HBmp;
Gdiplus::Graphics g(Image2->Canvas->Handle);
// 放大,其效果比StretchBlt好些
g.DrawImage(&GpBmp, Gdiplus::Rect(0, 0, Image2->Width, Image2->Height),
10, 10, 100, 100, UnitPixel);
// 也可放大,效果不好
// ::StretchBlt(Image2->Canvas->Handle, 0, 0, Image2->Width, Image2->Height,
// Image1->Canvas->Handle, 10, 10, 100, 100, 0xCC0020);
}
//---------------------------------------------------------------------------

#6


怎么把BCB问题发到VC板块?

#7


引用楼主 vick 的帖子:
首先说下 局部放大的含义: 
局部放大是指,由于某些控件大小与图片实际大小不符而导致显示不清楚,可以对图像实现 局部放大显示,不是单纯的放大屏幕。 


没看懂,感觉你是概念在解释概念

#8


放大屏幕就比如放大镜,模糊的图片仍然是模糊的,可能就是没有进行任何插值算法填充放大的空白点。

图片局部放大,比如图片本身很大,显示界面很小,进行了缩放后,你选择其中某一块,那么放大出来的可以是原图或者进行了插值算法填充后的,效果很好

#9


用BCB和VC都可以,哪种能解决用哪种。
谢谢各位,结帐给分。