• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            萬星星@豌豆莢 歡迎加入我們
            一個吃軟飯的男人!!!!!我只想寫程序####
            微博:http://weibo.com/wanlianwen
            posts - 172,  comments - 1253,  trackbacks - 0

            這里提及高效稍許有些夸張,僅為應景,因為本身就沒有太多高科技,權且作為一種有效的實現。

             

            首先是圖片解碼器的選擇。一般來講有幾種選擇:1、組裝各種開源庫,如libpng, libjpg, giflib等,支持什么格式就得添加對應的解碼器;2、開源解碼包,如freeimage,沒用過但聽說也很不錯;3、GDI+,支持圖片格式廣泛,接口簡單,性能一般。當然還有其它方式,大抵差不多。我選擇的是GDI+,圖簡便好用,且目前微軟支持的OS上都是自帶的,無需發布?!。對QQ的程序集DLL進行分析,發現其中貫穿了各種解碼技術,有直接采用開源庫的,也有依賴GDI+的,不知道是歷史遺留問題,還是各個部門之間技術偏好,抑或是另有玄機。扯到技術偏好,讓我頭疼的就是程序員在項目中隨意的引入庫,解決同一個問題,往往看到不同的人用不同的技術,甚至同一個人在不同的項目中造不同的輪子,有時候沒法說服別人,只能罷了。

             

            GDI+的初始化需要注意一件事情:不要在DLL入口處加載或卸載GDI+,否則會發生鎖死現象,具體可查閱msdn

             

            考慮到高性能的界面中可能會采用多線程UI,因此我建立了ThreadStateTLS對象,所有的數據都存儲在這個對象中,同步線程消息是通過慣用手法之隱藏窗口來保證。時至今日,或者早1、2年,我才深刻理解mfc庫設計時的那些state管理結構體的用處。GDI+的初始化在ThreadState構造函數中調用,正好避免了加載沖突這個問題。TLS對象的銷毀技巧來自谷歌的chromium源碼中的base庫里的tls實現,原始出處來自CodeProjecthttp://www.codeproject.com/threads/tls.asp。嗯,其實牛逼的程序員也是縱覽乾坤,吸取精華。提到CodeProject,順帶提一下我的學習歷程,早期瘋狂的泡這個網站,幾乎VC方面的東西都把玩過,形成了自己的點狀知識積累,類似的有CodeGuruvckbase(現在已經成為廣告站了);之后是 sourceforge、codegooglecodeplex 找一些小的項目研究,形成自己的線狀知識結構;再后來就是大型的源碼閱讀,偶爾會去谷歌討論組、微軟新聞組看一些疑難雜癥問題,構成了自己的面狀知識體系。每個人都有自己的學習方法論,這里僅僅是分享我自己的。很多東西都已經看上去有些過時,現在的年輕程序員可能接觸的是stackoverflow、github等。

             

            GDI+中的Image是抽象接口,為了方便使用,增加了一層簡易封裝IMImage,主要接口如下:

             

            static IMImage* FromFile(const std::wstring& uri);

            long AddRef();
            long Release();

            const std::wstring& uri() const { return uri_; }
            UINT frame_count() const { return frame_count_; }
            bool IsAnimate() const { return frame_count_ > 1; }
            long GetFrameDelay(UINT frame) const;
            long GetWidth() const;
            long GetHeight() const;
            Gdiplus::Image* GetImage(UINT frame);

             

            通過uri加載圖片,GDI+對本地圖片的加載非常簡單,Image::FromFile可以直接返回;對于網絡圖片,需要先通過WinINet下載到本地,然后再加載。

             

            由于使用了tls技術,這里的引用計數實現很簡單,就是++、-- 操作。曾經有人告訴我引用技術是為了解決多線程中對象的生命周期問題,我欲與否認。引用計數只是為了解決對象的生命周期問題,而這種情況往往在多線程中出現,因此多線程中或多或少會用到引用計數。

             

            IMImage類可以簡單的返回一些GDI+Image對象提供的圖片信息,而GetImage需要多做一些事情。對于包含多幀圖片的文件,在繪制的時候需要通過GDI+Image::SelectActiveFrame方法選擇當前幀,該操作非常耗時,因此在加載圖片的時候,發現如果是多幀的,我們需要額外的decode_image_來解碼存放每一幀圖像,這樣除第一次渲染比較耗時外,后面的獲取都是非??斓?。

             

            GetFrameDelay函數是獲取某一幀之間的時間間隔,通過GDI+PropertyItem可以很容易的獲取。需要指出的是PropertyItem類使用起來卻不是類的方式,需要手動new出一塊內存,所以這里用一個結構體我看更合適,而且還是C風格的。

            再增加一個IMImageService,管理整個系統中用到的IMImage對象,接口很簡單:

             

            IMImage* GetImage(const std::wstring& uri);
            void ReleaseImage(IMImage* image);

             

            需要圖像就找它要,用完之后記得釋放即可。

             

            這樣就完成了圖片的管理,目前來說足夠用,也非常簡單,不是么?

            posted on 2012-06-17 09:48 萬連文 閱讀(2953) 評論(2)  編輯 收藏 引用 所屬分類: richedit

            FeedBack:
            # re: richedit研究03 – 高效圖片管理
            2012-06-17 10:44 | 春秋十二月
            boost中也有tls的實現,早期的時候,我一直也想自己弄個tls,但至今沒動手,引用計數一是生命周期,二是共享資源。  回復  更多評論
              
            # re: richedit研究03 – 高效圖片管理
            2012-08-23 22:00 | 路障
            對于包含多幀圖片的文件,在繪制的時候需要通過GDI+的Image::SelectActiveFrame方法選擇當前幀,該操作非常耗時,因此在加載圖片的時候,發現如果是多幀的,我們需要額外的decode_image_來解碼存放每一幀圖像,這樣除第一次渲染比較耗時外,后面的獲取都是非常快的。

            解碼存放每一幀圖像,當一個GIF有很多幀的時候,也全部解碼出來,這樣會不會占用比較多的內存?  回復  更多評論
              
            簡歷下載
            聯系我

            <2007年4月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            常用鏈接

            留言簿(66)

            隨筆分類

            隨筆檔案

            相冊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            激情久久久久久久久久| 久久r热这里有精品视频| 四虎久久影院| 青草国产精品久久久久久| 久久99国产精品久久久| 久久亚洲高清综合| 久久丫精品国产亚洲av不卡| 久久精品国产只有精品66| 国内精品伊人久久久久777| 国产 亚洲 欧美 另类 久久| 久久久久亚洲精品日久生情 | 久久综合伊人77777麻豆| 亚洲欧美日韩中文久久| 久久人妻少妇嫩草AV无码蜜桃| 国产69精品久久久久9999APGF | 无码国内精品久久人妻麻豆按摩| 91久久婷婷国产综合精品青草 | 人妻无码精品久久亚瑟影视| 99久久精品国内| 亚洲综合日韩久久成人AV| 蜜臀久久99精品久久久久久| 国产精品久久久久久吹潮| 久久久久人妻精品一区| 免费一级欧美大片久久网| 一级做a爰片久久毛片16| 久久国产精品99精品国产| 亚洲va中文字幕无码久久| 香蕉aa三级久久毛片| 久久亚洲天堂| 久久久久国产日韩精品网站| 久久精品国产亚洲AV麻豆网站 | 无码人妻少妇久久中文字幕蜜桃| 曰曰摸天天摸人人看久久久| 久久精品国内一区二区三区| 国产精品99久久免费观看| 国产韩国精品一区二区三区久久| 亚洲AV乱码久久精品蜜桃| 久久精品国产亚洲av麻豆色欲| 中文字幕久久精品无码| 久久亚洲精品无码AV红樱桃| 成人免费网站久久久|