iOS展示超大圖片或超高分辨率圖片崩潰解決方法

前言:

ID作為一款以IM為基礎(chǔ)的辦公軟件逐哈,在用戶使用過程中,經(jīng)常會遇到一些超大的或者超高分辨率的圖片(以下統(tǒng)一稱:大圖)攒庵〔坜龋基于SDWebImage為基礎(chǔ)的圖片加載控件几睛,在遇到此情況時(shí),并沒有提供十分有效的解決方法(如果你谷歌或者百度粤攒,有很多回答所森,但實(shí)際并未能解決此問題)。曾經(jīng)一度困擾許久『唤樱現(xiàn)在將我的解決方式寫下來焕济,希望可以對你有所幫助。

參考:

作為IM軟件的領(lǐng)軍盔几,QQ與微信無疑給IM行業(yè)樹立了一個(gè)很好的榜樣晴弃。那我們就來看看它們是如何處理的(以下簡單描述,自己可以實(shí)際體驗(yàn)):

QQ:
點(diǎn)擊大圖瀏覽時(shí)逊拍,會有一個(gè)轉(zhuǎn)圈等待操作上鞠,對圖片放大的大小無限制。在放大過程中芯丧,圖片會模糊芍阎,停止操作后,一張清晰的高清圖渲染出來缨恒。如果圖片過大并分辨率超高(上萬)谴咸,會出現(xiàn)崩潰。

微信:
點(diǎn)擊大圖瀏覽時(shí)骗露,直接展示岭佳。但是對圖片展示大小有限制。放大到一定程度椒袍,無法繼續(xù)放大查看驼唱。

做為辦公軟件藻茂,無需解釋驹暑,很明顯QQ的方式更符合需求玫恳。

實(shí)現(xiàn):

對于大圖,壓縮肯定使我們需要的优俘,QQ轉(zhuǎn)圈等待同樣我猜測也是壓縮操作京办。

壓縮:
壓縮圖片我們希望可以保證壓縮的速度夠快及內(nèi)存消耗的盡可能小。在此感謝github上的OTLargeImageReader的作者帆焕,壓縮過程中內(nèi)存控制和速度都很好惭婿。

關(guān)鍵代碼:

//先從內(nèi)存中查找,查找不到再解碼叶雹,避免重復(fù)解碼
UIImage *cacheImage = [self.photoBrowser cacheImageWithPhoto:_photo];
if (cacheImage == nil) {
    //不存在财饥,解碼
    [self.photoBrowser showHUDWithSuperBigPhoto];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        CGSize compressSize = CGSizeMake(XXPhotoCompressPixelMax, XXPhotoCompressPixelMax);
        if (image.size.width > image.size.height) {
            compressSize = CGSizeMake(XXPhotoCompressPixelMax, XXPhotoCompressPixelMax*image.size.height/image.size.width);
        }
        else {
            compressSize = CGSizeMake(XXPhotoCompressPixelMax*image.size.width/image.size.height, XXPhotoCompressPixelMax);
        }
        UIImage *compressedImage = [image imageByScalingProportionallyToSize:compressSize];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.photoBrowser cacheImageWithPhoto:_photo image:compressedImage];
            self.showImageView.image = compressedImage;
            [self.photoBrowser hideHUDWithSuperBigPhoto];
            [self resetSize];
        });
    });
}
else {
    //直接使用
    self.showImageView.image = cacheImage;
}

通過以上方式,加上參考QQ的交互方式折晦,此時(shí)钥星,一張分辨率有限的大圖在經(jīng)過短暫壓縮處理后,已經(jīng)可以非常安全的在app中展示瀏覽了(緩存壓縮圖片避免重復(fù)壓縮)满着。但是谦炒,壓縮過的圖片放大后,模糊不清了风喇!這不能忍宁改,繼續(xù)搞。
當(dāng)在QQ中瀏覽圖片進(jìn)行放大時(shí)魂莫,可以很輕易的發(fā)現(xiàn)还蹲,此時(shí)的圖片也是模糊的(這就印證了轉(zhuǎn)圈過程中對圖片的壓縮操作),然而當(dāng)我們停止放大操作后耙考,當(dāng)前展示的模糊圖被重新渲染展示給我們秽誊,清晰,完美琳骡!
此時(shí)锅论,如果你遇到過這個(gè)問題,并且嘗試過解決楣号,你肯定找到了蘋果官方提供的Demo以及一些分塊加載的方式最易。這個(gè)成本太高,不建議炫狱。
思來想去藻懒,一個(gè)新的方式出現(xiàn)了:用戶在這個(gè)大圖中,關(guān)注的只有當(dāng)前屏幕中展示的這一區(qū)域的圖片视译,當(dāng)用戶不操作圖片時(shí)嬉荆,拿到圖片在手機(jī)屏幕上的元素覆蓋展示出來。用戶操作時(shí)酷含,移除覆蓋圖層鄙早,停止后重新操作汪茧。

裁剪圖片:
裁剪當(dāng)前屏幕中展示對應(yīng)原圖中的位置

- (void)didCutImage {
    if (_orImage) {
        if (self.scrollView.contentSize.width >= kScreenWidth &&
            self.scrollView.contentSize.height >= kScreenHeight) {
            CGFloat multipleF = _orImage.size.width/self.scrollView.contentSize.width;
            CGFloat width = kScreenWidth*multipleF;
            CGFloat height = kScreenHeight *multipleF;
            //如果剪切的尺寸過大,不處理
            if (width > XXPhotoPixelMax ||
                height > XXPhotoPixelMax) {
                return;
            }
            //如果剪切的尺寸過大限番,不處理
            //裁剪展示視圖
            if (_bigCupImageView) {
                _bigCupImageView.frame = CGRectMake(self.scrollView.contentOffset.x, self.scrollView.contentOffset.y, kScreenWidth, kScreenHeight);
            }
            else {
                [self.scrollView addSubview:self.bigCupImageView];
            }
            //裁剪展示視圖
            CGImageRef cgRef = _orImage.CGImage;
            CGImageRef imageRef = CGImageCreateWithImageInRect(cgRef, CGRectMake(self.scrollView.contentOffset.x *multipleF   ,self.scrollView.contentOffset.y *multipleF, width, height));
            UIImage *thumbScale = [UIImage imageWithCGImage:imageRef];
            CGImageRelease(imageRef);
            self.bigCupImageView.image = thumbScale;
        }
    }
}

在這個(gè)過程中舱污,仍需要注意的是,何時(shí)展示與隱藏剪切出來的圖片弥虐。
覆蓋圖片的添加與移除:
添加:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    [self performSelector:@selector(didCutImage) withObject:nil afterDelay:.5];
}

移除:

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view {
    if (_bigCupImageView) {
        [_bigCupImageView removeFromSuperview];
        _bigCupImageView = nil;
    }
}

結(jié)語:

此解決方式在實(shí)現(xiàn)上非常簡單扩灯,開始只是困于思路。如果你有其他的方式霜瘪,那我們就開始一段愉快的交流吧珠插!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市颖对,隨后出現(xiàn)的幾起案子丧失,更是在濱河造成了極大的恐慌,老刑警劉巖惜互,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件布讹,死亡現(xiàn)場離奇詭異,居然都是意外死亡训堆,警方通過查閱死者的電腦和手機(jī)描验,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坑鱼,“玉大人膘流,你說我怎么就攤上這事÷沉ぃ” “怎么了呼股?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長画恰。 經(jīng)常有香客問我彭谁,道長,這世上最難降的妖魔是什么允扇? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任缠局,我火速辦了婚禮,結(jié)果婚禮上考润,老公的妹妹穿的比我還像新娘狭园。我一直安慰自己,他們只是感情好糊治,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布唱矛。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绎谦。 梳的紋絲不亂的頭發(fā)上管闷,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音燥滑,去河邊找鬼。 笑死阿逃,一個(gè)胖子當(dāng)著我的面吹牛铭拧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播恃锉,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼搀菩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了破托?” 一聲冷哼從身側(cè)響起肪跋,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎土砂,沒想到半個(gè)月后州既,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡萝映,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年吴叶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片序臂。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蚌卤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奥秆,到底是詐尸還是另有隱情逊彭,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布构订,位于F島的核電站侮叮,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏悼瘾。R本人自食惡果不足惜签赃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望分尸。 院中可真熱鬧锦聊,春花似錦、人聲如沸箩绍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至圆到,卻和暖如春怎抛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芽淡。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工马绝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挣菲。 一個(gè)月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓富稻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親白胀。 傳聞我的和親對象是個(gè)殘疾皇子椭赋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,520評論 25 707
  • 人過了三十,總喜歡追憶一些曾經(jīng)或杠。不論是對的錯(cuò)的哪怔,也不論是輕狂還是蒼白。聽著慢悠悠的曲子向抢,慢慢的走路认境,左顧右盼。不知...
    e75036da13e3閱讀 243評論 0 1
  • 今天想談?wù)劇坝字伞边@個(gè)詞挟鸠,不知不覺間元暴,本偏貶義的這個(gè)詞已偏些許褒義,大家覺得幼稚一點(diǎn)挺好的兄猩,充滿童真茉盏,傻傻地單純地...
    銀一閱讀 190評論 2 2
  • 做人巍糯,我不喜歡戴面具 以真面目示人,我活得最真實(shí) 以真性情交人客扎,我活得最坦誠 以真感情對人祟峦,我活得最干凈 雖然我長...
    猜哪生活圈閱讀 486評論 0 1