随笔-341  评论-2670  文章-0  trackbacks-0
    自从我发现Windows XP开始就支持Windows Image Component之后,我发现读取图片这个问题瞬间就变简单了。因此我给GacUI添加了绘制图片的功能,并做了一个小小的GIF动画demo。代码仍然更新在了Vczh Library++3.0上的Candidate\GUI\GUIDemo\GUIDemo.sln上。F5可以直接运行,不过如果要双击打开exe的话,则要把GUIDemo\Resources目录复制到exe目录下。下面的效果图展示了一个GIF动画上覆盖若干个带有alpha通道的png图片:

(实际效果是会动的)

    因为GacUI试图隔离Windows API的所有信息,以便可以让程序员自由添加对操作系统(Windows或其他)和渲染技术(GDI、Direct2D或其他)的支持,因此我不得不暂时封装了一下。现在的这个接口只能读,不能做一些高级操作,以后会添加上。使用GacUI编写上述Demo的代码如下(具体实现可以去下载并阅读):
  1 #include "..\..\GUI\GacUI.h"
  2 
  3 GuiBoundsComposition* CreateImageFrame(Ptr<INativeImage> image, int frameIndex=0)
  4 {
  5     GuiImageFrameElement* element=GuiImageFrameElement::Create();
  6     element->SetImage(image, frameIndex);
  7 
  8     GuiBoundsComposition* composition=new GuiBoundsComposition;
  9     composition->SetOwnedElement(element);
 10     composition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElement);
 11     return composition;
 12 }
 13 
 14 class GifAnimation : public Object, public IGuiGraphicsAnimation
 15 {
 16 protected:
 17     unsigned __int64            startTime;
 18     GuiImageFrameElement*        element;
 19 public:
 20     GifAnimation(GuiImageFrameElement* _element)
 21         :element(_element)
 22         ,startTime(DateTime::LocalTime().totalMilliseconds)
 23     {
 24     }
 25 
 26     int GetTotalLength()
 27     {
 28         return 1;
 29     }
 30 
 31     int GetCurrentPosition()
 32     {
 33         return 0;
 34     }
 35 
 36     void Play(int currentPosition, int totalLength)
 37     {
 38         unsigned __int64 ms=DateTime::LocalTime().totalMilliseconds-startTime;
 39         int frameIndex=(ms/100)%element->GetImage()->GetFrameCount();
 40         element->SetImage(element->GetImage(), frameIndex);
 41     }
 42 
 43     void Stop()
 44     {
 45     }
 46 };
 47 
 48 void SetupGifWindow(GuiControlHost* host)
 49 {
 50     host->GetBoundsComposition()->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
 51     INativeImageProvider* imageProvider=GetCurrentController()->GetImageProvider();
 52     Ptr<INativeImage> imageNew=imageProvider->CreateImageFromFile(L"Resources\\New.png");
 53     Ptr<INativeImage> imageOpen=imageProvider->CreateImageFromFile(L"Resources\\Open.png");
 54     Ptr<INativeImage> imageSave=imageProvider->CreateImageFromFile(L"Resources\\Save.png");
 55     Ptr<INativeImage> imageGif=imageProvider->CreateImageFromFile(L"Resources\\Gif.gif");
 56 
 57     GuiBoundsComposition* image1=CreateImageFrame(imageNew);
 58     GuiBoundsComposition* image2=CreateImageFrame(imageOpen);
 59     GuiBoundsComposition* image3=CreateImageFrame(imageSave);
 60     GuiBoundsComposition* image4=CreateImageFrame(imageGif);
 61     
 62     host->GetContainerComposition()->AddChild(image4);
 63     host->GetContainerComposition()->AddChild(image1);
 64     host->GetContainerComposition()->AddChild(image2);
 65     host->GetContainerComposition()->AddChild(image3);
 66 
 67     image1->SetBounds(Rect(Point(1010), imageNew->GetFrame(0)->GetSize()));
 68     image2->SetBounds(Rect(Point(5010), imageOpen->GetFrame(0)->GetSize()));
 69     image3->SetBounds(Rect(Point(9010), imageSave->GetFrame(0)->GetSize()));
 70 
 71     Ptr<GifAnimation> animation=new GifAnimation(image4->GetOwnedElement().Cast<GuiImageFrameElement>().Obj());
 72     host->GetGraphicsHost()->GetAnimationManager()->AddAnimation(animation);
 73 }
 74 
 75 /***********************************************************************
 76 GuiMain
 77 ***********************************************************************/
 78 
 79 void GuiMain()
 80 {
 81     INativeWindow* window=GetCurrentController()->CreateNativeWindow();
 82 #ifdef GUI_GRAPHICS_RENDERER_GDI
 83     window->SetTitle(L"Vczh GUI Demo (GDI)");
 84 #endif
 85 #ifdef GUI_GRAPHICS_RENDERER_DIRECT2D
 86     window->SetTitle(L"Vczh GUI Demo (Direct2D)");
 87 #endif
 88     window->SetClientSize(Size(800600));
 89 
 90     INativeScreen* screen=GetCurrentController()->GetScreen(window);
 91     Rect windowBounds=window->GetBounds();
 92     Rect screenBounds=screen->GetClientBounds();
 93     window->SetBounds(Rect(
 94         Point(
 95             screenBounds.Left()+(screenBounds.Width()-windowBounds.Width())/2,
 96             screenBounds.Top()+(screenBounds.Height()-windowBounds.Height())/2
 97             ),
 98         windowBounds.GetSize()
 99         ));
100 
101     GuiControlHost host(new win7::Win7WindowStyle);
102     SetupGifWindow(&host);
103     host.SetNativeWindow(window);
104 
105     GetCurrentController()->Run(window);
106 }


posted on 2011-11-06 01:00 陈梓瀚(vczh) 阅读(2217) 评论(5)  编辑 收藏 引用 所属分类: GacUI

评论:
# re: GacUI支持包括GIF和PNG在内的多种图片格式 2011-11-06 18:28 | phoenixbing
一个女人,拿着鞭子,太邪恶了.  回复  更多评论
  
# re: GacUI支持包括GIF和PNG在内的多种图片格式 2011-11-06 21:21 | ISA-信息科学社
命名方式值得大家学习。  回复  更多评论
  
# re: GacUI支持包括GIF和PNG在内的多种图片格式 2011-11-06 21:26 | 陈梓瀚(vczh)
@phoenixbing
寒蝉鸣泣之时,神片啊  回复  更多评论
  
# re: GacUI支持包括GIF和PNG在内的多种图片格式 2011-11-07 20:23 | iloveprogramme
@陈梓瀚(vczh)
要确实是神片的话去看看。
现在除了在追几部有限的漫画外,挺长时间不看动画了。
  回复  更多评论
  
# re: GacUI支持包括GIF和PNG在内的多种图片格式 2011-11-07 20:53 | 陈梓瀚(vczh)
@iloveprogramme
两部都要看完,否则会不知所云的。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理