• <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>
            萬(wàn)星星@豌豆莢 歡迎加入我們
            一個(gè)吃軟飯的男人!!!!!我只想寫程序####
            微博:http://weibo.com/wanlianwen
            posts - 172,  comments - 1253,  trackbacks - 0

            這里提及高效稍許有些夸張,僅為應(yīng)景,因?yàn)楸旧砭蜎](méi)有太多高科技,權(quán)且作為一種有效的實(shí)現(xiàn)。

             

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

             

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

             

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

             

            GDI+中的Image是抽象接口,為了方便使用,增加了一層簡(jiǎn)易封裝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);

             

            通過(guò)uri加載圖片,GDI+對(duì)本地圖片的加載非常簡(jiǎn)單,Image::FromFile可以直接返回;對(duì)于網(wǎng)絡(luò)圖片,需要先通過(guò)WinINet下載到本地,然后再加載。

             

            由于使用了tls技術(shù),這里的引用計(jì)數(shù)實(shí)現(xiàn)很簡(jiǎn)單,就是++-- 操作。曾經(jīng)有人告訴我引用技術(shù)是為了解決多線程中對(duì)象的生命周期問(wèn)題,我欲與否認(rèn)。引用計(jì)數(shù)只是為了解決對(duì)象的生命周期問(wèn)題,而這種情況往往在多線程中出現(xiàn),因此多線程中或多或少會(huì)用到引用計(jì)數(shù)。

             

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

             

            GetFrameDelay函數(shù)是獲取某一幀之間的時(shí)間間隔,通過(guò)GDI+PropertyItem可以很容易的獲取。需要指出的是PropertyItem類使用起來(lái)卻不是類的方式,需要手動(dòng)new出一塊內(nèi)存,所以這里用一個(gè)結(jié)構(gòu)體我看更合適,而且還是C風(fēng)格的。

            再增加一個(gè)IMImageService,管理整個(gè)系統(tǒng)中用到的IMImage對(duì)象,接口很簡(jiǎn)單:

             

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

             

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

             

            這樣就完成了圖片的管理,目前來(lái)說(shuō)足夠用,也非常簡(jiǎn)單,不是么?

            posted on 2012-06-17 09:48 萬(wàn)連文 閱讀(2969) 評(píng)論(2)  編輯 收藏 引用 所屬分類: richedit

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

            解碼存放每一幀圖像,當(dāng)一個(gè)GIF有很多幀的時(shí)候,也全部解碼出來(lái),這樣會(huì)不會(huì)占用比較多的內(nèi)存?  回復(fù)  更多評(píng)論
              
            簡(jiǎn)歷下載
            聯(lián)系我

            <2012年5月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            常用鏈接

            留言簿(66)

            隨筆分類

            隨筆檔案

            相冊(cè)

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久精品日日躁夜夜躁欧美| 国产国产成人精品久久| 久久精品中文字幕第23页| 久久精品亚洲精品国产欧美| 一本久久久久久久| 国内精品久久久久久久久| 久久亚洲AV成人无码| 国内精品伊人久久久久777| 久久99精品久久只有精品| 久久久久国产日韩精品网站| 久久久久免费精品国产| 国内精品久久久久久久久电影网| 伊色综合久久之综合久久| 中文字幕成人精品久久不卡| 99久久精品免费看国产一区二区三区| 香蕉久久一区二区不卡无毒影院| 亚洲欧洲精品成人久久奇米网| 久久精品国产福利国产秒| 亚洲伊人久久成综合人影院 | 久久99精品国产99久久6| 久久午夜夜伦鲁鲁片免费无码影视 | 久久99精品九九九久久婷婷| 久久天天躁狠狠躁夜夜96流白浆 | 久久久亚洲欧洲日产国码是AV| 久久99国产精品久久久| 精品久久久中文字幕人妻| 亚洲人成无码网站久久99热国产| 一级做a爰片久久毛片人呢| 国产精品99久久精品| 久久精品人人槡人妻人人玩AV| 伊人久久无码精品中文字幕| 久久国产精品二国产精品| 7国产欧美日韩综合天堂中文久久久久| 人妻无码久久一区二区三区免费 | 欧美伊人久久大香线蕉综合| 亚洲一区精品伊人久久伊人| 亚洲国产精品综合久久网络| 久久频这里精品99香蕉久| 欧美一区二区久久精品| 精品无码久久久久国产动漫3d| 精品久久久久久国产|