【IOS開發(fā)高級(jí)系列】異步繪制專題

1 圖片處理

1.1 編輯圖片的幾個(gè)方法

第一種

????先用UIImage對(duì)象加載一張圖片

????然后轉(zhuǎn)化成CGImageRef放到CGContext中去編輯


第二種

????用CGImageCreate函數(shù)創(chuàng)建CGImageRef

????然后把CGImageRef放到CGContext中去編輯


第三種

????用CGImageCreateCopy 或者CGImageCreateCopyWithColorSpace函數(shù)拷貝

CGImageRefCGImageCreate (

????size_t width, //圖片的寬度

????size_t height, //圖片的高度

????size_t bitsPerComponent,? //圖片每個(gè)顏色的bits檩奠,比如rgb顏色空間辅斟,有可能是5 或者8 ==

????size_t bitsPerPixel,? //每一個(gè)像素占用的buts内地,15 位24位 32位等等

????size_t bytesPerRow, //每一行占用多少bytes 注意是bytes不是bits ?1byte =8bit

????CGColorSpaceRef colorspace,? //顏色空間茁肠,比如rgb

????CGBitmapInfo bitmapInfo,? //layout,像素中bit的布局, 是rgba還是 argb,==

????CGDataProviderRef provider,? //數(shù)據(jù)源提供者,url或者內(nèi)存==

????const CGFloat decode[],? //一個(gè)解碼數(shù)組

????bool shouldInterpolate,? //抗鋸齒參數(shù)

????CGColorRenderingIntent intent

????//圖片渲染相關(guān)參數(shù)

);

1.2 示例代碼

CGImageRef CGImageCreate(size_t width, size_theight, size_tbitsPerComponent, size_t bitsPerPixel, size_tbytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, CGDataProviderRefprovider, const CGFloat decode[], boolshouldInterpolate, CGColorRenderingIntent intent);

????通過這個(gè)方法雏掠,我們可以創(chuàng)建出一個(gè)CGImageRef類型的對(duì)象,下面分別對(duì)參數(shù)進(jìn)行解釋:

????sizt_t是定義的一個(gè)可移植性的單位劣像,在64位機(jī)器中為8字節(jié)乡话,32位位4字節(jié)。

????width:圖片寬度像素

????height:圖片高度像素

????bitsPerComponent:每個(gè)顏色的比特?cái)?shù)驾讲,例如在rgba-32模式下為8

????bitsPerPixel:每個(gè)像素的總比特?cái)?shù)

????bytesPerRow:每一行占用的字節(jié)數(shù)蚊伞,注意這里的單位是字節(jié)

????space:顏色空間模式席赂,例如const CFStringRef kCGColorSpaceGenericRGB 這個(gè)函數(shù)可以返回一個(gè)顏色空間對(duì)象。

????bitmapInfo:位圖像素布局时迫,枚舉如下:

typedef?CF_OPTIONS(uint32_t,?CGBitmapInfo)?{

??kCGBitmapAlphaInfoMask?=?0x1F,

??kCGBitmapFloatComponents?=?(1?<<?8),

??kCGBitmapByteOrderMask?=?0x7000,

??kCGBitmapByteOrderDefault?=?(0?<<?12),

??kCGBitmapByteOrder16Little?=?(1?<<?12),

??kCGBitmapByteOrder32Little?=?(2?<<?12),

??kCGBitmapByteOrder16Big?=?(3?<<?12),

??kCGBitmapByteOrder32Big?=?(4?<<?12)

}

????provider:數(shù)據(jù)源提供者

????decode[]:解碼渲染數(shù)組

????shouldInterpolate:是否抗鋸齒

????intent:圖片相關(guān)參數(shù)


CGImageRef CGImageMaskCreate(size_t width, size_theight, size_t bitsPerComponent, size_t bitsPerPixel, size_tbytesPerRow, CGDataProviderRef provider, const CGFloat decode[], boolshouldInterpolate)

????這個(gè)方法用于創(chuàng)建mask圖片圖層颅停,可以設(shè)置其顯示部分與不顯示部分達(dá)到特殊的效果,參數(shù)意義同上掠拳。

CGImageRef CGImageCreateCopy(CGImageRefimage)

????這個(gè)方法可以復(fù)制一個(gè)CGImageRef對(duì)象

CGImageRef CGImageCreateWithJPEGDataProvider(CGDataProviderRef source, const CGFloat decode[], boolshouldInterpolate, CGColorRenderingIntent intent)

????通過JPEG數(shù)據(jù)源獲取圖像

CGImageRef CGImageCreateWithPNGDataProvider(CGDataProviderRefsource, const CGFloat decode[], boolshouldInterpolate, CGColorRenderingIntent intent)

????通過PNG數(shù)據(jù)源獲取圖像

CGImageRef CGImageCreateWithImageInRect(CGImageRefimage, CGRectrect)

????截取圖像的一個(gè)區(qū)域重繪圖像

CGImageRef CGImageCreateWithMask(CGImageRef image, CGImageRefmask)

????截取mask圖像的某一區(qū)域重繪

CGImageRef CGImageCreateWithMaskingColors(CGImageRefimage, const CGFloatcomponents[])

????通過顏色分量數(shù)組創(chuàng)建位圖

CGImageRef CGImageCreateCopyWithColorSpace(CGImageRefimage, CGColorSpaceRef space)

????通過顏色空間模式復(fù)制位圖

CGImageRef CGImageRetain(CGImageRefimage)

????引用+1

void CGImageRelease(CGImageRefimage)

????引用-1

bool CGImageIsMask(CGImageRefimage)

????返回是否為Mask圖層

size_t CGImageGetWidth(CGImageRefimage)

????獲取寬度像素

size_t CGImageGetHeight(CGImageRefimage)

獲取高度像素


下面這些方法分別獲取相應(yīng)屬性

size_t CGImageGetBitsPerComponent(CGImageRefimage)

size_t CGImageGetBitsPerPixel(CGImageRefimage)

size_t CGImageGetBytesPerRow(CGImageRefimage)

CGColorSpaceRef CGImageGetColorSpace(CGImageRef image)CG_EXTERN CGImageAlphaInfo CGImageGetAlphaInfo(CGImageRefimage)

CGDataProviderRef CGImageGetDataProvider(CGImageRefimage)

const CGFloat *CGImageGetDecode(CGImageRefimage)

bool CGImageGetShouldInterpolate(CGImageRefimage)

CGColorRenderingIntent CGImageGetRenderingIntent(CGImageRefimage)

CGBitmapInfo CGImageGetBitmapInfo(CGImageRefimage)


1.3 PNG與JPEG優(yōu)劣比較

????存儲(chǔ)速度:JPG更快

????壓縮比:JPG更大癞揉;

????圖片質(zhì)量:JPG更好

????JPG不支持透明效果;????

????UIImageJPEGRepresentation方法在耗時(shí)上比較少 而UIImagePNGRepresentation耗時(shí)操作時(shí)間比較長(zhǎng)溺欧;

????UIImageJPEGRepresentation函數(shù)需要兩個(gè)參數(shù):圖片的引用和壓縮系數(shù).而UIImagePNGRepresentation只需要圖片引用作為參數(shù).通過在實(shí)際使用過程中,比較發(fā)現(xiàn): UIImagePNGRepresentation(UIImage* image) 要比UIImageJPEGRepresentation(UIImage* image, 1.0) 返回的圖片數(shù)據(jù)量大很多.譬如,同樣是讀取攝像頭拍攝的同樣景色的照片, UIImagePNGRepresentation()返回的數(shù)據(jù)量大小為199K ,而 UIImageJPEGRepresentation(UIImage* image, 1.0)返回的數(shù)據(jù)量大小只為140KB,比前者少了50多KB.如果對(duì)圖片的清晰度要求不高,還可以通過設(shè)置 UIImageJPEGRepresentation函數(shù)的第二個(gè)參數(shù),大幅度降低圖片數(shù)據(jù)量.譬如,剛才拍攝的圖片, 通過調(diào)用UIImageJPEGRepresentation(UIImage* image, 1.0)讀取數(shù)據(jù)時(shí),返回的數(shù)據(jù)大小為140KB,但更改壓縮系數(shù)后,通過調(diào)用UIImageJPEGRepresentation(UIImage* image, 0.5)讀取數(shù)據(jù)時(shí),返回的數(shù)據(jù)大小只有11KB多,大大壓縮了圖片的數(shù)據(jù)量 ,而且從視角角度看,圖片的質(zhì)量并沒有明顯的降低.因此,在讀取圖片數(shù)據(jù)內(nèi)容時(shí),建議優(yōu)先使用UIImageJPEGRepresentation,并可根據(jù)自己的實(shí)際使用場(chǎng)景,設(shè)置壓縮系數(shù),進(jìn)一步降低圖片數(shù)據(jù)量大小.


1.4 圖片縮放

圖片縮放的三個(gè)函數(shù)

http://www.cnblogs.com/pengyingh/articles/2355052.html

????????程序中一個(gè)界面用到了好多張大圖喊熟,內(nèi)存報(bào)警告了,所以做了一下圖片縮放姐刁,在網(wǎng)上找了別人寫的代碼

//把圖片做等比縮放芥牌,生成一個(gè)新圖片

- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize sourceImage:(UIImage*)sourceImage {

//????UIGraphicsBeginImageContext(targetSize);

//? ? [sourceImage drawInRect:CGRectMake(0,0, targetSize.width, targetSize.height)];

//? ? UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext();

//????UIGraphicsEndImageContext();

//????return scaledImage;

? ? UIImage*newImage = nil;

? ?CGSize imageSize = sourceImage.size;

? ?CGFloat width = imageSize.width;

? ?CGFloat height = imageSize.height;

? ?CGFloat targetWidth = targetSize.width;

? ?CGFloat targetHeight = targetSize.height;

? ?CGFloat scaleFactor =0.0;

? ?CGFloat scaledWidth = targetWidth;

? ?CGFloat scaledHeight = targetHeight;

? ?CGPoint thumbnailPoint = CGPointMake(0.0,0.0);


? ?UIGraphicsBeginImageContext(targetSize);// this will crop

? ?CGRect thumbnailRect = CGRectZero;

? ?thumbnailRect.origin = thumbnailPoint;

? ?thumbnailRect.size.width? = scaledWidth;

? ?thumbnailRect.size.height = scaledHeight;


? ?[sourceImage drawInRect:thumbnailRect];


? ?newImage =UIGraphicsGetImageFromCurrentImageContext();

? ?if(newImage== nil)

? ? ? ? NSLog(@"could not scale image");

? ? ? ?//pop thecontext to get back to the default

? ? ? ?UIGraphicsEndImageContext();

? ? ? ?return newImage;

}

//把圖片按照新大小進(jìn)行裁剪,生成一個(gè)新圖片

- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize image:(UIImage *)sourceImage

{

? ? //??? UIImage*sourceImage = self;

? ? UIImage*newImage = nil;

? ?CGSizeimageSize = sourceImage.size;

? ?CGFloat width= imageSize.width;

? ?CGFloat height= imageSize.height;

? ?CGFloattargetWidth = targetSize.width;

? ?CGFloattargetHeight = targetSize.height;

? ?CGFloat scaleFactor =0.0;

? ?CGFloat scaledWidth = targetWidth;

? ?CGFloat scaledHeight = targetHeight;

? ?CGPoint thumbnailPoint = CGPointMake(0.0,0.0);


? ?if(CGSizeEqualToSize(imageSize, targetSize) == NO)

? ?{

? ? ? ?CGFloat widthFactor = targetWidth /width;

? ? ? ?CGFloat heightFactor = targetHeight / height;

? ? ? ?if(widthFactor > heightFactor)

? ? ? ? ? ?scaleFactor = widthFactor;// scale to fit height

? ? ? ?else

? ? ? ? ? ?scaleFactor = heightFactor;// scale to fit width


? ? ? ?scaledWidth? = width * scaleFactor;

? ? ? ?scaledHeight = height * scaleFactor;


? ? ? ?// centerthe image

? ? ? ?if (widthFactor > heightFactor)

? ? ? ?{

? ? ? ? ? ?thumbnailPoint.y = (targetHeight -scaledHeight) *0.5;

? ? ? ?}

? ? ? ?else

? ? ? ? ? ?if(widthFactor < heightFactor)

? ? ? ? ? ?{

? ? ? ? ? ? ? ?thumbnailPoint.x =(targetWidth - scaledWidth) *0.5;

? ? ? ? ? ?}

? ?}??????


? ?UIGraphicsBeginImageContext(targetSize);// this will crop

? ?CGRect thumbnailRect = CGRectZero;

? ?thumbnailRect.origin = thumbnailPoint;

? ?thumbnailRect.size.width? = scaledWidth;

? ?thumbnailRect.size.height = scaledHeight;

? ?[sourceImage drawInRect:thumbnailRect];


? ?newImage =UIGraphicsGetImageFromCurrentImageContext();

? ?if (newImage== nil)

? ? ? ?NSLog(@"could not scale image");


? ?//pop thecontext to get back to the default

? ?UIGraphicsEndImageContext();

? ?return newImage;

}


- (UIImage*)generatePhotoThumbnail:(UIImage *)image

{

? ? // Create a thumbnail version of the image for the eventobject.

? ? CGSize size =image.size;

? ? CGSize croppedSize;

? ? CGFloat ratio=64.0;//這個(gè)是設(shè)置轉(zhuǎn)換后圖片的尺寸大小

? ? ?CGFloat offsetX =0.0;

? ? ?CGFloat offsetY =0.0;


? ? // check the size of the image, we want to make it

????// a square with sides the size of the smallest dimension

? ?if(size.width > size.height) {

? ? ? ?offsetX = (size.height - size.width) /2;

? ? ? ?croppedSize = CGSizeMake(size.height, size.height);

? ?}else{

? ? ? ?offsetY = (size.width - size.height) /2;

? ? ? ?croppedSize = CGSizeMake(size.width, size.width);

? ?}


? ?// Crop the image before resize

? ?CGRect clippedRect = CGRectMake(offsetX *-1, offsetY * -1, croppedSize.width, croppedSize.height);

????//裁剪圖片

????CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], clippedRect);

? ?// Donecropping


????// Resize the image

? ? CGRect rect = CGRectMake(0.0,0.0,ratio, ratio);

? ? UIGraphicsBeginImageContext(rect.size);

? ? [[UIImage imageWithCGImage: imageRef] drawInRect: rect];

? ? UIImage *thumbnail =UIGraphicsGetImageFromCurrentImageContext();

? ? UIGraphicsEndImageContext();

? ? // DoneResizing


? ? return thumbnail;

}


實(shí)際應(yīng)用簡(jiǎn)化

-(UIImage *)generatePhotoThumbnail:(UIImage *)image

{

??? CGRect rect=CGRectMake(0,0,60,78);

????//裁剪圖片

??? CGImageRefimageRef=CGImageCreateWithImageInRect([image CGImage], CGRectMake(0,0,140,182));


??? UIGraphicsBeginImageContext(rect.size);

??? [[UIImage imageWithCGImage:imageRef]drawInRect:rect];

????//如果不裁剪圖片可以直接畫

??? //[image drawInRect:CGRectMake(0, 0,theSize.width, theSize.height)];

??? UIImage*thumbnail=UIGraphicsGetImageFromCurrentImageContext();

??? UIGraphicsEndImageContext();

??? returnthumbnail;

}


附:

UIImage類并沒有提供縮放圖片需要用到的API聂使,是不是覺得很吃驚壁拉?沒關(guān)系,我們自己來添加一個(gè)柏靶。

定義縮放圖片的Category

//? UIImage+Scale.h

@interfaceUIImage (scale)

-(UIImage*)scaleToSize:(CGSize)size;

@end


實(shí)現(xiàn)這個(gè)Category的定義

// UIImage+Scale.m?


#import"UIImage+Scale.h"

@implementation UIImage (scale)

-(UIImage*)scaleToSize:(CGSize)size

{

????// 創(chuàng)建一個(gè)bitmap的context

????// 并把它設(shè)置成為當(dāng)前正在使用的context

? ? UIGraphicsBeginImageContext(size);

? ? // 繪制改變大小的圖片

????[self drawInRect: CGRectMake(0,0, size.width, size.height)];


? ? ?// 從當(dāng)前context中創(chuàng)建一個(gè)改變大小后的圖片

? ? ?UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext();


? ????// 使當(dāng)前的context出堆棧

? ????UIGraphicsEndImageContext();

? ????// 返回新的改變大小后的圖片

????return scaledImage;

}

@end


如何使用

// 創(chuàng)建圖片

UIImage*image =[UIImage imageNamed:@"myImage.png"];

// 更改圖片大小

UIImage *scaledImage=[image scaleToSize:CGSizeMake(25.0f,35.0f)]


1.5 參考鏈接

IOS-圖片操作集合

http://blog.csdn.net/ch_soft/article/details/7685753

UIImagePNGRepresentation存在緩慢問題

http://blog.sina.com.cn/s/blog_95a3991f010162ws.html

UIImage變?yōu)镹SData并進(jìn)行壓縮

http://www.cnblogs.com/robinkey/archive/2013/01/21/2869930.html

UIImageJPEGRepresentation和UIImagePNGRepresentation

http://blog.csdn.net/mideveloper/article/details/11473627

png有透明通道弃理,JPEG無

http://blog.163.com/chentong1115@126/blog/static/45314732200972323921819/

透明PNG圖片有黑邊的解決方法

http://www.minroad.com/?p=9

用UIImage和UIButton畫出的按鈕,使用透明的png圖片屎蜓,為什么會(huì)出現(xiàn)白邊

http://segmentfault.com/q/1010000000095447

JPG痘昌、PNG和GIF圖片的基本原理及優(yōu)化方法

http://www.mahaixiang.cn/Photoshop/400.html

JPEG原理詳細(xì)

http://blog.chinaunix.net/uid-27002868-id-3220554.html

IOS開發(fā)中圖片資源使用png還是jpg格式

http://www.cnblogs.com/wengzilin/p/3485298.html

(good)ios開發(fā)圖片格式的選擇:png和jpg

http://m.blog.csdn.net/blog/awaylin113/22712317

IOS開發(fā)之保存圖片到Documents目錄及PNG,JPEG格式相互轉(zhuǎn)換

http://blog.csdn.net/sanpintian/article/details/7418755

iOS過濾png圖片透明部分點(diǎn)擊事件

http://www.cocoachina.com/industry/20121127/5192.html

JPEG壓縮原理

http://blog.csdn.net/xfortius/article/details/8904012

png壓縮原理

http://blog.csdn.net/zykun/article/details/1825086

iOS開發(fā)炬转,圖片使用png好還是jpg好辆苔?

http://www.cocoachina.com/bbs/read.php?tid=110115


2 繪制文本

2.1 NSMutableAttributedString繪制

CGRect textViewRect = CGRectMake(ICON_SPACE, _imageHeight + ICON_SPACE, _postContentTextView.frame.size.width, _labelSize);

NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString: vm.contentText];

[str addAttribute:NSForegroundColorAttributeName value: kContentTextColor range:NSMakeRange(0,[vm.contentText length])];

[str addAttribute: NSFontAttributeName value: kContentTextFont range:NSMakeRange(0,[vm.contentText length])];

[str addAttribute: NSBackgroundColorDocumentAttribute value: [UIColor whiteColor] range: NSMakeRange(0, [vm.contentText length])];

[str drawInRect: textViewRect];


2.2 參考資料

IOS開發(fā)(78)之繪制文本

http://www.2cto.com/kf/201305/212045.html

iOS界面上繪制不同字體 顏色 大小的字符串

http://blog.csdn.net/wsk_123_123/article/details/23277457

初探NSAttributedString和NSMutableAttributedString的使用-LiuWJ

http://www.tuicool.com/articles/Fvqia2

iOS字符屬性NSAttributedString描述

http://my.oschina.net/lanrenbar/blog/395909

NSAttributedString詳解

http://www.cnblogs.com/zhw511006/archive/2012/09/21/2696700.html


3 異步繪制

3.1 異步繪制示例

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

???????CGRect drawRect = _bgImageView.frame;

???????UIGraphicsBeginImageContextWithOptions(drawRect.size, YES, 0);

???????CGContextRef context = UIGraphicsGetCurrentContext();


???????if(!context) {

???????????return;

???????}


???????[[UIColor whiteColor] set];

???????CGContextFillRect(context, drawRect);


???????CGRect imgRect = CGRectZero;

???????if ([vm.contentImgPath length] > 0) {

???????????imgRect =CGRectMake(0, 0, BODY_HEIGTH, _imageHeight);

???????????[vm.contentImage drawInRect:? contentImageView.frame blendMode: kCGBlendModeNormal alpha:1];

???????}


???????CGRect textViewRect = CGRectZero;

?????? ?if ([vm.contentText length] > 0) {

??????????? NSMutableAttributedString*str;

??????????? if (!isContentDisplayCompletly) {

??????????????? if (vm.digestText) {

??????????????????? str = [[NSMutableAttributedString alloc] initWithString: vm.digestText attributes: contentTextView.typingAttributes];

??????????????? }else

??????????????????? str = [[NSMutableAttributedString alloc] initWithString: vm.contentText attributes: contentTextView.typingAttributes];

??????????? }else

??????????????? str = [[NSMutableAttributedString alloc] initWithString: vm.contentText attributes: contentTextView.typingAttributes];

??????????? [strdrawInRect: contentTextView.frame];

??????? }


??????? if (_subjectTitleHeight> 0) {

??????? ????CGRect subjectIconFrame = CGRectMake(_subjectButton.frame.origin.x, _subjectButton.frame.origin.y, 16, 16);

??????????? UIImage*iconImg = [UIImage imageNamed:@"FlagIcon"];

??????????? subjectIconFrame.size = iconImg.size;

??????????? [iconImg drawInRect: subjectIconFrame blendMode: kCGBlendModeNormal alpha:1];

??????????? CGRect subjectTitleFrame = CGRectMake(subjectIconFrame.origin.x + subjectIconFrame.size.width, subjectIconFrame.origin.y, 100, _subjectTitleHeight);

??????????? [_subjectButton.titleLabel.attributedText drawInRect: subjectTitleFrame];

??????? }


??????? UIImage*temp = UIGraphicsGetImageFromCurrentImageContext();

??????? UIGraphicsEndImageContext();


??????? dispatch_async(dispatch_get_main_queue(),^{

??????????? _bgImageView.image = nil;

??????????? _bgImageView.image=temp;

??????????? [self setHidden:NO];

??????? });

??? });


3.2 DrawRect之后注意用hitTest:withEvent:方法處理事件接收

//用戶觸摸時(shí)第一時(shí)間加載內(nèi)容

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event{

??? UIView*result = [super hitTest: point withEvent: event];

??? CGPoint buttonPoint = [_subjectButton convertPoint: point fromView: self];

??? if ([_subjectButton pointInside:buttonPointwithEvent:event]){

??????? return _subjectButton;

??? }

??? returnresult;

}


3.3 參考鏈接

[iOS Animation]-CALayer繪圖效率-異步繪制

http://my.oschina.net/u/2438875/blog/507545?fromerr=R4LnEaJ5

CGDataProviderCreateWithData對(duì)內(nèi)存數(shù)據(jù)的釋放

http://www.taofengping.com/2012/11/04/cgdataprovidercreatewithdata_memory_release/#.VnJQ6jaitZF

IOS中使用像素位圖(CGImageRef)對(duì)圖片進(jìn)行處理

http://my.oschina.net/u/2340880/blog/406437?p={{currentPage-1}}


4 Asyncdisplaykit

4.1 參考鏈接

Asyncdisplaykit指南(一)

http://www.th7.cn/Program/IOS/201410/302413.shtml

AsyncDisplayKit教程:達(dá)到60FPS的滾動(dòng)幀率

http://www.cocoachina.com/swift/20141124/10298.html

http://asyncdisplaykit.org/guide/

AsyncDisplayKit入門指南

http://www.cocoachina.com/ios/20141020/9975.html


5 開發(fā)技巧

5.1 常見問題

5.1.1 CGBitmapContextCreateImage繪制后內(nèi)存泄露導(dǎo)致內(nèi)存告警

????????CGBitmapContextCreateImage繪制的圖片會(huì)造成內(nèi)存無法釋放,應(yīng)該換用CGDataProviderCreateWithCFData扼劈。

5.1.1.1 方案一:修改源代碼姑子,入緩存前壓縮

http://my.oschina.net/u/1244672/blog/510379

SDWebImage有一個(gè)SDWebImageDownloaderOperation類來執(zhí)行下載操作的。里面有個(gè)下載完成的方法:

- (void)connectionDidFinishLoading:(NSURLConnection*)aConnection {

????SDWebImageDownloaderCompletedBlock completionBlock = self.completedBlock;

????@synchronized(self) {

????????CFRunLoopStop(CFRunLoopGetCurrent());

????????self.thread =?nil;

????????self.connection= nil;

????????[[NSNotificationCenter defaultCenter] postNotificationName: SDWebImageDownloadStopNotificati onobject: nil];

????}


????if (![[NSURLCache sharedURLCache] cachedResponseForRequest:_request]) {

????????responseFromCached= NO;

????}


? ? if(completionBlock)

????{

????if(self.options & SDWebImageDownloaderIgnoreCachedResponse &&responseFromCached) {

????????completionBlock(nil, nil, nil, YES);

????}

????else {

????????UIImage *image= [UIImage sd_imageWithData: self.imageData];

????????NSString *key= [[SDWebImageManager sharedManager] cacheKeyForURL: self.request.URL];

????????image = [self scaledImageForKey: key image: image];


????????// Do notforce decoding animated GIFs

????????if (!image.images) {

????????????image = [UIImage decodedImageWithImage: image];

????????}

????????if (CGSizeEqualToSize(image.size, CGSizeZero)) {

????????????completionBlock(nil, nil, [NSError errorWithDomain:@"SDWebImageErrorDomain" code:0userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0pixels"}], YES);

????????}

????????else {

????????????completionBlock(image, self.imageData, nil, YES);

????????}

????}

}

self.completionBlock= nil;

[self done];

}


其中测僵,UIImage*image = [UIImage sd_imageWithData:self.imageData];就是將data轉(zhuǎn)換成image。

再看看sd_imageWithData:這個(gè)方法:

+ (UIImage*)sd_imageWithData:(NSData *)data {

????UIImage*image;

????NSString*imageContentType = [NSData sd_contentTypeForImageData: data];


????if ([imageContentType isEqualToString:@"image/gif"]) {

????????image =[UIImage sd_animatedGIFWithData: data];

????}

#ifdefSD_WEBP

????else if([imageContentType isEqualToString:@"image/webp"])

????{

????????image =[UIImage sd_imageWithWebPData: data];

????}

#endif

????else {

????????image =[[UIImage alloc] initWithData: data];

????????UIImageOrientation orientation = [self sd_imageOrientationFromImageData: data];

????????if(orientation != UIImageOrientationUp) {

????????????image =[UIImage imageWithCGImage: image.CGImage scale: image.scale orientation: orientation];

????????}

????}

????return image;

}

????????這個(gè)方法在UIImage+MultiFormat里面谢翎,是UIImage的一個(gè)類別處理捍靠。這句話很重要image =[[UIImage alloc] initWithData: data]; SDWebImage把下載下來的data直接轉(zhuǎn)成image,然后沒做等比縮放直接存起來使用森逮。所以榨婆,我們只需要在這邊做處理即可:

UIImage+MultiFormat添加一個(gè)方法:

+(UIImage*)compressImageWith:(UIImage *)image

{

????float imageWidth = image.size.width;

????float imageHeight = image.size.height;

????float width =640;

????float height =image.size.height/(image.size.width/width);

????float widthScale = imageWidth /width;

????float heightScale = imageHeight /height;


????// 創(chuàng)建一個(gè)bitmap的context

????// 并把它設(shè)置成為當(dāng)前正在使用的context

????UIGraphicsBeginImageContext(CGSizeMake(width, height));


????if (widthScale> heightScale) {

????????[image drawInRect: CGRectMake(0, 0, imageWidth /heightScale , height)];

????}

????else {

????????[image drawInRect: CGRectMake(0, 0, width , imageHeight /widthScale)];

????}


????// 從當(dāng)前context中創(chuàng)建一個(gè)改變大小后的圖片

????UIImage*newImage = UIGraphicsGetImageFromCurrentImageContext();

????// 使當(dāng)前的context出堆棧

????UIGraphicsEndImageContext();


????return newImage;

}


????然后在:image =[[UIImage alloc] initWithData: data];下面調(diào)用以下:

if (data.length/1024 > 1024) {

????image = [self compressImageWith: image];

}


????當(dāng)data大于1M的時(shí)候做壓縮處理。革命尚未成功褒侧,還需要一步處理良风。在SDWebImageDownloaderOperation的connectionDidFinishLoading方法里面的:

UIImage *image= [UIImage sd_imageWithData: self.imageData];

//將等比壓縮過的image在賦在轉(zhuǎn)成data賦給self.imageData

NSData *data =UIImageJPEGRepresentation(image, 1);

self.imageData = [NSMutableData dataWithData: data];


5.1.1.2 方案二:設(shè)置全局緩存大小

http://www.myexception.cn/swift/2033029.html

1谊迄、首先在appdelegate方法didFinishLaunchingWithOptions

SDImageCache.sharedImageCache().maxCacheSize=1024*1024*8設(shè)置一下最大的緩存大小。

2烟央、在appdelegate?applicationDidReceiveMemoryWarning里加入

SDImageCache.sharedImageCache().clearMemory()

SDWebImageManager.sharedManager().cancelAll()


5.1.1.3 方案三:定時(shí)清理內(nèi)存緩存

http://www.bubuko.com/infodetail-956863.html

????經(jīng)過嘗試统诺,發(fā)現(xiàn)了一個(gè)最簡(jiǎn)單的完美解決該問題的方法

????在使用SDWebImage加載較多圖片造成內(nèi)存警告時(shí),定期調(diào)用

?[[SDImageCache sharedImageCache] setValue:nilforKey:@"memCache"];


5.1.1.4 方案四(不推薦):修復(fù)SD庫代碼疑俭,不做解壓粮呢,直接返回壓縮的原圖

5.1.1.5 方案五(推薦):使用CGDataProviderRef進(jìn)行圖形解壓重繪

iOS開發(fā)中界面展示大圖片時(shí)UIImage的性能有關(guān)問題

http://www.myexception.cn/operating-system/578931.html

#import "SDWebImageDecoder.h"


@implementationUIImage (ForceDecode)


+ (UIImage*)decodedImageWithImage:(UIImage*)image {

??? if (image.images) {

???????// Do not decode animated images

???????return image;

??? }


??? UIImage *decompressedImage;

????@autoreleasepool{

????????//核心代碼,可以解決內(nèi)存未釋放問題

??????? NSData *data = UIImageJPEGRepresentation(image, 1);

??????? CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

??????? CGImageRef imageRef = CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO, kCGRenderingIntentDefault);


????//??? CGImageRef imageRef = image.CGImage;

??? ????CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef));

??? ????CGRect imageRect = (CGRect){.origin = CGPointZero, .size=imageSize};

??? ????CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

??? ????CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);


??????? int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask);

??? ????BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone || infoMask == kCGImageAlphaNoneSkipFirst || infoMask ==kCGImageAlphaNoneSkipLast);


??? ????// CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB.

??? ????//https://developer.apple.com/library/mac/#qa/qa1037/_index.html

??? ????if (infoMask == kCGImageAlphaNone&& CGColorSpaceGetNumberOfComponents(colorSpace)

> 1) {

??????? ????// Unset the old alpha info.

??????? ????bitmapInfo &= ~kCGBitmapAlphaInfoMask;

?? ?????????// Set noneSkipFirst.

??????? ????bitmapInfo |= kCGImageAlphaNoneSkipFirst;

??? ????}

??????????? // Some PNGs tell us they have alpha but only 3 components. Odd.

??? ????else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace)

== 3) {

??????? ????????// Unset the old alpha info.

??????? ????????bitmapInfo &= ~kCGBitmapAlphaInfoMask;

??????? ????????bitmapInfo |=kCGImageAlphaPremultipliedFirst;

??? ????????}


??? // It calculates the bytes-per-row based on the bitsPerComponent and width arguments.

??? ????????CGContextRef context = CGBitmapContextCreate(NULL,

??????????? imageSize.width,

??????????? imageSize.height,

??????????? CGImageGetBitsPerComponent(imageRef), 0, colorSpace, bitmapInfo);

??? ????????CGColorSpaceRelease(colorSpace);


??? ????????// If failed, return undecompressed image

??? ????????if (!context) return image;


??? ????????CGContextDrawImage(context, imageRect, imageRef);

??? ????????CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);

??????????? CGContextRelease(context);


??? ????????decompressedImage = [UIImage imageWithCGImage: decompressedImageRef scale: image.scale orientation: image.imageOrientation];

??? ????????CGImageRelease(decompressedImageRef);

? ? ? ?}


????????//??? CVPixelBufferRef pixelBuffer;? ?

????????//???CreateCGImageFromCVPixelBuffer(pixelBuffer,&decompressedImageRef);

????????//??? CGImage *cgImage =CGBitmapContextCreateImage(context);

????????//??? CFDataRef dataRef =CGDataProviderCopyData(CGImageGetDataProvider(cgImage));

????????//??? CGImageRelease(cgImage);

????????//??? image->imageRef = dataRef;

????????//??? image->image = CFDataGetBytePtr(dataRef);

??? return decompressedImage;

}


5.1.2 UIImage自定義繪制的四種方法

///方法中會(huì)自動(dòng)做縮放處理

+(void) getBitmapImage: (UIImage *)image Size: (CGSize)imageSize WithCompletionBlock:(HJCallbackBlock)block

{

? ? ? ?dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

??????? ????UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0);

??????? ????CGContextRef context = UIGraphicsGetCurrentContext();


??????? ????if(!context) {

??????????? ????dispatch_async(dispatch_get_main_queue(), ^{

??????????????? ????block(image);

??????????? ????});

??????? ????}


??????? ????CGRect rect = CGRectMake(0, 0, imageSize.width, imageSize.height);

??????? ????//坐標(biāo)系統(tǒng)已經(jīng)自動(dòng)考慮了縮放因素钞艇,不需要額外處理

??????? ????[image drawInRect: rect blendMode: kCGBlendModeNormal alpha:1];

??????? ????UIImage *temp = UIGraphicsGetImageFromCurrentImageContext();

??????? ????NSData *tempData = UIImageJPEGRepresentation(temp, 1);

??????? ????UIGraphicsEndImageContext();


??????? ????//設(shè)置SDWebImage庫的緩存

??????? ????NSString *device = [HJUtility getCurDeviceModel];

??????? ????if ([device rangeOfString:@"iPhone 4"].length > 0) {

??????????? ????if (tempData.length > 500000) {

??????????????? ????tempData =UIImageJPEGRepresentation(temp, 0.4);

??????????????? }


??????????? ????temp = [UIImage imageWithData: tempData];

??????? }


??????? dispatch_async(dispatch_get_main_queue(), ^{

??????????? if(block) {

??????????????? block(temp);

??????????? }

??????? });

??? });


??? //方案二啄寡,內(nèi)存有釋放,掛機(jī)

??? //???UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);

??? //

??? //???CGContextRef context = UIGraphicsGetCurrentContext();

??? //???CGRect rect = CGRectMake(0, 0, imageSize.width * [UIScreenmainScreen].scale, imageSize.height * [UIScreen mainScreen].scale);

??? //???// draw alpha-mask

??? ////???CGContextSetBlendMode(context, kCGBlendModeNormal);

??? //???CGContextDrawImage(context, rect, image.CGImage);

??? //???// draw tint color, preserving alpha values of original image

??? ////???CGContextSetBlendMode(context, kCGBlendModeSourceIn);

??? //

??? //???CGContextFillRect(context, rect);

??? //

??? //???//Set the original greyscale template as the overlay of the new image

??? //???UIImage *imgData = [self verticallyFlipImage:image];

??? //???[imgData drawInRect:imageRect];

??? //???UIImage *colouredImage = UIGraphicsGetImageFromCurrentImageContext();

??? //???UIGraphicsEndImageContext();

??? //???colouredImage = [self verticallyFlipImage:colouredImage];

??? //?? ?CGContextRelease(context);

??? //???return colouredImage;


??? //方案三哩照,CGBitmapContextCreate方案挺物,內(nèi)存沒釋放

??? //???CGFloat targetWidth = imageSize.width * [UIScreen mainScreen].scale;

??? //???CGFloat targetHeight = imageSize.height * [UIScreen mainScreen].scale;

??? //???CGImageRef imageRef = [image CGImage];

??? //???CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);

??? //???CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);

??? //???CGContextRef bitmapContext;

??? //???bitmapContext = CGBitmapContextCreate(NULL, targetWidth,targetHeight,CGImageGetBitsPerComponent(imageRef),CGImageGetBytesPerRow(imageRef),colorSpaceInfo, bitmapInfo);

??? //???CGContextDrawImage(bitmapContext, CGRectMake(0, 0, targetWidth,targetHeight), imageRef);

??? //

??? //???CGImageRef imgref = CGBitmapContextCreateImage(bitmapContext);

??? //???UIImage* newImage = [UIImage imageWithCGImage:imgref];

??? //

??? //???CGColorSpaceRelease(colorSpaceInfo);

??? //???CGContextRelease(bitmapContext);

??? //???CGImageRelease(imgref);

??? //

??? //???return newImage;


??? //方案四,CGBitmapContextCreate方案飘弧,但是采用CGDataProviderCreateWithCFData方案解決內(nèi)存占用問題

??? //???NSData *data = UIImageJPEGRepresentation(image, 1);

??? //???CGDataProviderRef dataProvider =CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

??? //???CGImageRef imageRef = CGImageCreateWithJPEGDataProvider(dataProvider,

??? //??????????????????????????????????????????????????????????NULL, NO,

??? //??????????????? ???????????????????????????????????????????kCGRenderingIntentDefault);

??? //

??? //???CGFloat targetWidth = imageSize.width * [UIScreen mainScreen].scale;

??? //???CGFloat targetHeight = imageSize.height * [UIScreen mainScreen].scale;

??? //???//????? ??CGImageRef imageRef = [image CGImage];

??? //

??? //???CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);

??? //

??? //???CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);

??? //???CGContextRef bitmapContext;

??? //???bitmapContext = CGBitmapContextCreate(NULL, targetWidth,targetHeight,CGImageGetBitsPerComponent(imageRef),0, colorSpaceInfo,bitmapInfo);

??? //???CGContextDrawImage(bitmapContext, CGRectMake(0, 0, targetWidth,targetHeight), imageRef);

??? //

??? //???// If failed, return undecompressed image

??? //???if (!bitmapContext) return image;

??? //

??? //???CGImageRef imgref = CGBitmapContextCreateImage(bitmapContext);

??? //???UIImage* newImage = [UIImage imageWithCGImage:imgref];//[UIImageimageWithCGImage:decompressedImageRef scale:image.scaleorientation:image.imageOrientation];

??? //???

??? //???CGColorSpaceRelease(colorSpaceInfo);

??? //???CGContextRelease(bitmapContext);

??? //???CGImageRelease(imgref);

??? //???

??? //???return newImage;

}


5.1.3 繪制時(shí)單元格底部出現(xiàn)高度不定的細(xì)微黑線

問題原因:

?????? 將Text做寬高計(jì)算時(shí)识藤,高度值容易得出小數(shù)數(shù)值,而頁面繪制均是基于整數(shù)像素點(diǎn)繪制眯牧,對(duì)于小數(shù)點(diǎn)部分蹋岩,系統(tǒng)會(huì)做舍去處理(即便有縮放),固留下高度不定的未繪制區(qū)域(為黑色)学少。


解決方案:

?????? 將計(jì)算出來的高度值做向下取整處理即可剪个。

CGRect labelFrame = [content boundingRectWithSize: size options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:_postContentTextView.typingAttributes context: nil];

labelSize = labelFrame.size;

labelSize.height = ceilf(labelSize.height);


6 參考鏈接

(GOOD)iOS開發(fā)中界面展示大圖片時(shí)UIImage的性能有關(guān)問題

http://www.myexception.cn/operating-system/578931.html

(Good)iPhone - UIImage Leak, CGBitmapContextCreateImage Leak

http://stackoverflow.com/questions/1427478/iphone-uiimage-leak-cgbitmapcontextcreateimage-leak

Another iPhone - CGBitmapContextCreateImage Leak

http://stackoverflow.com/questions/1434714/another-iphone-cgbitmapcontextcreateimage-leak

UIGraphicsBeginImageContext vs CGBitmapContextCreate

http://stackoverflow.com/questions/4683448/uigraphicsbeginimagecontext-vs-cgbitmapcontextcreate

iPhone - CGBitmapContextCreateImage Leak, Anyone else withthis problem?

http://stackoverflow.com/questions/1431566/iphone-cgbitmapcontextcreateimage-leak-anyone-else-with-this-problem

Build and Analyze false positive on leak detection?

http://stackoverflow.com/questions/8438249/build-and-analyze-false-positive-on-leak-detection

iPhone - Multiple CGBitmapContextCreateImage Calls -ObjectAlloc climbing

http://stackoverflow.com/questions/1436465/iphone-multiple-cgbitmapcontextcreateimage-calls-objectalloc-climbing

(Good)ios開發(fā)圖片處理,內(nèi)存泄露

http://www.oschina.net/question/736524_69802

主題:CGBitmapContextCreateImage(bitmap)內(nèi)存泄露問題處理

http://www.cocoachina.com/bbs/read.php?tid=31835

iOS異步圖片加載優(yōu)化與常用開源庫分析

http://luoyibu.com/2015/05/12/iOS異步圖片加載優(yōu)化與常用開源庫分析/

主題:圖片處理開源函數(shù)ImageProcessing? CGDataProviderCreateWithData Bug修復(fù)

http://www.cocoachina.com/bbs/read.php?tid=116149

CGDataProviderCreateWithData對(duì)內(nèi)存數(shù)據(jù)的釋放

http://www.taofengping.com/2012/11/04/cgdataprovidercreatewithdata_memory_release/#.VmpqgoSitZE

IOS7.x下UIGraphicsGetImageFromCurrentImageContext引發(fā)內(nèi)存暴漲版确,導(dǎo)致應(yīng)用被結(jié)束掉

http://blog.163.com/l1_jun/blog/static/1438638820155593641529/

在iOS中與CGContextRef的內(nèi)存泄漏

http://www.itstrike.cn/Question/55b86ce7-dfba-4548-a103-22dc5317420a.html

使用AFNetworking, SDWebimage和OHHTTPStubs

http://blog.shiqichan.com/using-afnetworking-sdwebimage-and-ohhttpstubs/

SDWebImage緩存圖片的機(jī)制(轉(zhuǎn))

http://blog.csdn.net/zhun36/article/details/8900327

近來一個(gè)swift項(xiàng)目用uicollectionview 用sdwebimage 加載圖片扣囊,發(fā)生內(nèi)存猛增,直接閃退的情況绒疗,簡(jiǎn)單說一下解決方案

http://www.myexception.cn/swift/2033029.html

關(guān)于SDWebImage加載高清圖片導(dǎo)致app崩潰的問題

http://www.bubuko.com/infodetail-956863.html

SDWebImage加載大圖導(dǎo)致的內(nèi)存警告問題

http://blog.csdn.net/richer1997/article/details/43481959

解決MWPhotoBrowser中的SDWebImage加載大圖導(dǎo)致的內(nèi)存警告問題

http://my.oschina.net/u/1244672/blog/510379

使用SDWebImage加載大量圖片后造成內(nèi)存泄露的解決辦法

http://www.bubuko.com/infodetail-985746.html

UIGraphicsBeginImageContext系列知識(shí)

http://blog.sina.com.cn/s/blog_5fb39f9101017n1v.html

iOS繪圖教程

http://blog.csdn.net/nogodoss/article/details/18660153

CGBitmapContextCreate函數(shù)

http://blog.csdn.net/thanklife/article/details/25790433

UIGraphicsBeginImageContext創(chuàng)建的映像停留在內(nèi)存中永恒

http://codego.net/589714/

多次在cell中加載網(wǎng)絡(luò)圖片后侵歇,內(nèi)存增長(zhǎng),以前資源未釋放

http://bbs.csdn.net/topics/390891681

請(qǐng)問下面的代碼有潛在的內(nèi)存泄漏吓蘑?

http://codego.net/459077/

[ios]UIGraphicsGetImageFromCurrentImageContext()-內(nèi)存泄漏

http://www.itstrike.cn/Question/88ada9bd-911c-44a7-874b-e04c1a1c2bca.html

[轉(zhuǎn)載]ios開發(fā)之View屬性hidden, opaque, alpha的區(qū)別

http://blog.sina.com.cn/s/blog_7da2c9030101ev8n.html

利用預(yù)渲染加速iOS設(shè)備的圖像顯示

http://www.keakon.net/2011/07/26/利用預(yù)渲染加速iOS設(shè)備的圖像顯示

iOS使用CGContextRef繪制各種圖形

http://www.devstore.cn/essay/essayInfo/116.html

iOS CGContextRef畫圖小結(jié)

http://blog.sina.com.cn/s/blog_9693f61a0101deko.html

IOS用CGContextRef畫各種圖形(文字惕虑、圓、直線磨镶、弧線溃蔫、矩形、扇形琳猫、橢圓伟叛、三角形、圓角矩形脐嫂、貝塞爾曲線统刮、圖片)

http://blog.csdn.net/rhljiayou/article/details/9919713

iOS畫圖 以及清空

http://blog.csdn.net/woshidaniu/article/details/46683409


7 Quartz 2D

7.1 參考鏈接

iOS通過Quartz畫矩形紊遵、文字、線

http://blog.csdn.net/onlyou930/article/details/7726399

Quartz 2D參考-文本

http://blog.csdn.net/kmyhy/article/details/7258338

Quartz 2D (ProgrammingWithQuartz) note

http://renxiangzyq.iteye.com/blog/1188025

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末侥蒙,一起剝皮案震驚了整個(gè)濱河市暗膜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辉哥,老刑警劉巖桦山,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異醋旦,居然都是意外死亡恒水,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門饲齐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钉凌,“玉大人,你說我怎么就攤上這事捂人∮瘢” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵滥搭,是天一觀的道長(zhǎng)酸纲。 經(jīng)常有香客問我,道長(zhǎng)瑟匆,這世上最難降的妖魔是什么闽坡? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮愁溜,結(jié)果婚禮上疾嗅,老公的妹妹穿的比我還像新娘。我一直安慰自己冕象,他們只是感情好代承,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布舶斧。 她就那樣靜靜地躺著聋袋,像睡著了一般蜡峰。 火紅的嫁衣襯著肌膚如雪喧兄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天稿壁,我揣著相機(jī)與錄音辩尊,去河邊找鬼赎婚。 笑死只锻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的紫谷。 我是一名探鬼主播齐饮,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼捐寥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了祖驱?” 一聲冷哼從身側(cè)響起握恳,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎捺僻,沒想到半個(gè)月后乡洼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匕坯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年束昵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片葛峻。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锹雏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出术奖,到底是詐尸還是另有隱情礁遵,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布采记,位于F島的核電站佣耐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏唧龄。R本人自食惡果不足惜兼砖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望选侨。 院中可真熱鬧掖鱼,春花似錦、人聲如沸援制。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晨仑。三九已至褐墅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洪己,已是汗流浹背妥凳。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留答捕,地道東北人逝钥。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像拱镐,于是被迫代替她去往敵國和親艘款。 傳聞我的和親對(duì)象是個(gè)殘疾皇子持际,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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