GPUImage 實現(xiàn)自定義相機

前言

  • 這是基于第三方庫GPUImage實現(xiàn)的自定義相機瑰谜,主要是功能方面的實現(xiàn),在UI上暫時并沒有做很好的完善。主要包括功能有實時濾鏡树绩,準確聚焦萨脑,調(diào)整焦距,調(diào)整曝光饺饭,閃光燈設置渤早,翻轉(zhuǎn)前后相機以及拍照后的濾鏡調(diào)整等

引入GPUImage庫

  • 主要有工程以依賴的形式加入GPUImage或者用Pod安裝GPUImage的方法,網(wǎng)上類似教程很多砰奕,這里就不贅述了

制作自定義相機

新建一個CameraViewController,作為實時相機界面的Controller,并且做以下預處理及聲明變量

#define HEIGHT 667.0
#define WIDTH 375.0
static int CameraFilterCount = 9;//濾鏡的數(shù)量

///濾鏡View的顯示狀態(tài)
typedef NS_ENUM(NSInteger, FilterViewState) {
    
    FilterViewHidden,/**<隱藏*/
    
    FilterViewUsing /**<顯示*/
};

///閃光燈狀態(tài)
typedef NS_ENUM(NSInteger, CameraManagerFlashMode) {
    
    CameraManagerFlashModeAuto, /**<自動*/
    
    CameraManagerFlashModeOff, /**<關閉*/
    
    CameraManagerFlashModeOn /**<打開*/
};

@interface CameraViewController() <UIGestureRecognizerDelegate>
{
    CALayer *_focusLayer; //聚焦層
}

///新建相機cameraManager
@property (nonatomic,strong) GPUImageStillCamera *cameraManager;

/**
*根據(jù)storyboard上將界面分為三個View蛛芥,預覽View,底部View以及整體的cameraView,也可以用代碼實現(xiàn)
*/
@property (strong, nonatomic) IBOutlet UIView *cameraView;
@property (weak, nonatomic) IBOutlet UIView *preview;
@property (weak, nonatomic) IBOutlet UIView *bottomView;

@property CameraFilterView *cameraFilterView;//自定義濾鏡視圖

@property (nonatomic , assign) CameraManagerFlashMode flashMode;
@property (nonatomic , assign) FilterViewState filterViewState;

@property (nonatomic , weak) IBOutlet UIButton *flashButton;//閃光燈按鈕

@property (nonatomic , assign) CGFloat beginGestureScale;//開始的縮放比例
@property (nonatomic , assign) CGFloat effectiveScale;//最后的縮放比例

@property GPUImageOutput *filter;//濾鏡
@property GPUImageView *filterView;//實時濾鏡預覽視圖
@property AVCaptureStillImageOutput *photoOutput;//用于保存原圖

@property CheckViewController *checkVC;//拍照之后跳轉(zhuǎn)的ViewController
@end

控制器視圖方法

- (void)viewDidLoad{
//隱藏導航欄
    [self.navigationController setNavigationBarHidden:YES];
//從SB初始化CheckController军援,后續(xù)解釋FilterCode
    _checkVC = [[self storyboard] instantiateViewControllerWithIdentifier:@"Check"];
    [_checkVC setFilterCode:0];

//初始化相機仅淑,默認為前置相機
    _cameraManager = [[MyCamera alloc] initWithSessionPreset:AVCaptureSessionPresetPhoto cameraPosition:AVCaptureDevicePositionFront];
    _cameraManager.outputImageOrientation = UIInterfaceOrientationPortrait;//設置照片的方向為設備的定向
    _cameraManager.horizontallyMirrorFrontFacingCamera = YES;//設置是否為鏡像
    _cameraManager.horizontallyMirrorRearFacingCamera = NO;

    _filter = [[GPUImageFilter alloc] init];//初始化濾鏡,默認初始化為原圖GPUImageFilter

    [self setfocusImage:[UIImage imageNamed:@"touch_focus_x"]];//初始化聚焦圖片
/**
*設置cameraManager的輸出對象為filter,然后將preview強制轉(zhuǎn)換為filterView添加到filter的輸出對象中胸哥,這樣在filterView中顯示的就是相機捕捉到的并且經(jīng)過filter濾鏡處理的實時圖像了
*/
    [self.cameraManager addTarget:_filter];
    _filterView = (GPUImageView *)self.preview;
    [_filter addTarget:_filterView];

//初始化閃光燈模式為Auto
    [self setFlashMode:CameraManagerFlashModeAuto];
//默認濾鏡視圖為隱藏涯竟,就是點擊濾鏡的按鈕才會出現(xiàn)讓你選擇濾鏡的那個小視圖
    [self setFilterViewState:FilterViewHidden];
//初始化開始及結(jié)束的縮放比例都為1.0
    [self setBeginGestureScale:1.0f];
    [self setEffectiveScale:1.0f];
 //啟動相機捕獲
    [self.cameraManager startCameraCapture];}

UI方法

  • 這里先給出CameraFilterView的實現(xiàn)方法,其實就是一個簡單的一行的CollectionView空厌,博主比較懶庐船,引用了ShawnDu大哥的代碼,在此表示感謝??
///.h文件
#import <UIKit/UIKit.h>

@protocol CameraFilterViewDelegate;

@interface CameraFilterView : UICollectionView <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>

@property (strong, nonatomic) NSMutableArray *picArray;//圖片數(shù)組
@property (strong, nonatomic) id <CameraFilterViewDelegate> cameraFilterDelegate;
@end

@protocol CameraFilterViewDelegate <NSObject>

- (void)switchCameraFilter:(NSInteger)index;//濾鏡選擇方法

@end
\\\.m文件
#import "CameraFilterView.h"
static const float CELL_HEIGHT = 84.0f;
static const float CELL_WIDTH = 56.0f;
@implementation CameraFilterView

#pragma mark 初始化方法

- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout{
    self = [super initWithFrame:frame collectionViewLayout:layout];
    if (self) {
        self.delegate = self;
        self.dataSource = self;
    }
    return self;
}

#pragma mark collection 方法
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return [_picArray count];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *identifier = @"cameraFilterCellID";
    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:identifier];
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, CELL_WIDTH, CELL_HEIGHT)];
    imageView.image = [_picArray objectAtIndex:indexPath.row];
    [cell addSubview:imageView];
    cell.backgroundColor = [UIColor whiteColor];
    
    return cell;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    return CGSizeMake(CELL_WIDTH, CELL_HEIGHT);
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    [_cameraFilterDelegate switchCameraFilter:indexPath.row];
}

-(BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
@end
  • 關于Collection控件不懂的同學可以先復習一下CollectionView或者用其他的方法實現(xiàn)自定義控件
//添加濾鏡視圖到主視圖上
- (void)addCameraFilterView {
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    _cameraFilterView = [[CameraFilterView alloc] initWithFrame:CGRectMake(0, HEIGHT - _bottomView.frame.size.height - (WIDTH-4)/5 - 4, WIDTH, (WIDTH-4)/5) collectionViewLayout:layout];
    NSMutableArray *filterNameArray = [[NSMutableArray alloc] initWithCapacity:CameraFilterCount];
    for (NSInteger index = 0; index < CameraFilterCount; index++) {
        UIImage *image = [UIImage imageNamed:@"girl"];
        [filterNameArray addObject:image];
    }
    _cameraFilterView.cameraFilterDelegate = self;
    _cameraFilterView.picArray = filterNameArray;
    [self.view addSubview:_cameraFilterView];
}

//使用濾鏡
- (IBAction)useFilter:(id)sender {
    if (self.filterViewState == FilterViewHidden) {
        [self addCameraFilterView];
        [self setFilterViewState:FilterViewUsing];
    }
    else {
        [_cameraFilterView removeFromSuperview];
        [self setFilterViewState:FilterViewHidden];
    }
}

//設置聚焦圖片
- (void)setfocusImage:(UIImage *)focusImage {
    if (!focusImage) return;
    
    if (!_focusLayer) {
    //增加tap手勢嘲更,用于聚焦及曝光
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(focus:)];
        [self.preview addGestureRecognizer:tap];
     //增加pinch手勢筐钟,用于調(diào)整焦距   
        UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(focusDisdance:)];
        [self.preview addGestureRecognizer:pinch];
        pinch.delegate = self;
    }

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, focusImage.size.width, focusImage.size.height)];
    imageView.image = focusImage;
    CALayer *layer = imageView.layer;
    layer.hidden = YES;
    [self.preview.layer addSublayer:layer];
    _focusLayer = layer;

}

//點擊閃光燈按鈕
- (IBAction)changeFlash:(id)sender {
    [self changeFlashMode:_flashButton];
}

濾鏡選擇方法的實現(xiàn)

/**
*以下的濾鏡是GPUImage自帶的濾鏡,后面有幾個效果不是很明顯赋朦,我只是拿來做測試用篓冲。
*GPUImage自帶的濾鏡很多李破,大家可以都試試看,當然也可以自己寫濾鏡壹将,這就需要后續(xù)深入學習了
*對checkViewController中filtercode屬性的說明:filtercode是在選擇濾鏡的時候設置嗤攻,
*在拍照的時候傳值給CheckViewController,實際上拍照傳遞給CheckVC的是原圖加上當前設置的filtercode诽俯,
*所以在后續(xù)CheckVC中改變?yōu)V鏡的時候是基于原圖進行改變妇菱。
*/
- (void)switchCameraFilter:(NSInteger)index {
    [self.cameraManager removeAllTargets];
    switch (index) {
        case 0:
            _filter = [[GPUImageFilter alloc] init];//原圖
            [_checkVC setFilterCode:0];
            break;
        case 1:
            _filter = [[GPUImageHueFilter alloc] init];//綠巨人
            [_checkVC setFilterCode:1];
            break;
        case 2:
            _filter = [[GPUImageColorInvertFilter alloc] init];//負片
            [_checkVC setFilterCode:2];
            break;
        case 3:
            _filter = [[GPUImageSepiaFilter alloc] init];//老照片
            [_checkVC setFilterCode:3];
            break;
        case 4: {
            _filter = [[GPUImageGaussianBlurPositionFilter alloc] init];
            [(GPUImageGaussianBlurPositionFilter*)_filter setBlurRadius:40.0/320.0];
            [_checkVC setFilterCode:4];
        }
            break;
        case 5:
            _filter = [[GPUImageSketchFilter alloc] init];//素描
            [_checkVC setFilterCode:5];
            break;
        case 6:
            _filter = [[GPUImageVignetteFilter alloc] init];//黑暈
            [_checkVC setFilterCode:6];
            break;
        case 7:
            _filter = [[GPUImageGrayscaleFilter alloc] init];//灰度
            [_checkVC setFilterCode:7];
            break;
        case 8:
            _filter = [[GPUImageToonFilter alloc] init];//卡通效果 黑色粗線描邊
            [_checkVC setFilterCode:8];
        default:
            _filter = [[GPUImageFilter alloc] init];
            [_checkVC setFilterCode:9];
            break;
    }
    
    [self.cameraManager addTarget:_filter];
    [_filter addTarget:_filterView];
}

拍照方法的實現(xiàn)

- (IBAction)takePhoto:(id)sender {
    _photoOutput = [_cameraManager getPhotoOutput];//得到源數(shù)據(jù)輸出流
    NSDictionary * outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil];
    //這是輸出流的設置參數(shù)AVVideoCodecJPEG參數(shù)表示以JPEG的圖片格式輸出圖片
    [_photoOutput setOutputSettings:outputSettings];
    AVCaptureConnection *captureConnection=[_photoOutput connectionWithMediaType:AVMediaTypeVideo];
    //根據(jù)連接取得設備輸出的數(shù)據(jù)
    [_photoOutput captureStillImageAsynchronouslyFromConnection:captureConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
        if (imageDataSampleBuffer) {
            NSData *imageData=[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
            UIImage *image=[UIImage imageWithData:imageData];
//將輸出流數(shù)據(jù)轉(zhuǎn)換成NSData,然后通過NSData將數(shù)據(jù)轉(zhuǎn)換為UIImage傳遞給checkVC
            _checkVC.image = image;
            [self.navigationController pushViewController:_checkVC animated:YES];
        }  
    }];
}

轉(zhuǎn)置攝像頭

#pragma mark 轉(zhuǎn)置攝像頭

- (IBAction)turn:(id)sender {
    [self.cameraManager stopCameraCapture];
    if (_cameraManager.cameraPosition == AVCaptureDevicePositionFront) {
        [_cameraManager initWithSessionPreset:AVCaptureSessionPresetPhoto cameraPosition:AVCaptureDevicePositionBack];
    }
    else if(_cameraManager.cameraPosition == AVCaptureDevicePositionBack)
    {
        [_cameraManager initWithSessionPreset:AVCaptureSessionPresetPhoto cameraPosition:AVCaptureDevicePositionFront];
    }
    _cameraManager.outputImageOrientation = UIInterfaceOrientationPortrait;
    _cameraManager.horizontallyMirrorFrontFacingCamera = YES;
    _cameraManager.horizontallyMirrorRearFacingCamera = NO;
    
    [self.cameraManager addTarget:_filter];
    _filterView = (GPUImageView *)self.preview;
    [_filter addTarget:_filterView];
    
    [self setBeginGestureScale:1.0f];//在轉(zhuǎn)換攝像頭的時候把攝像頭的焦距調(diào)回1.0
    [self setEffectiveScale:1.0f];
    
    [self.cameraManager startCameraCapture];
}

調(diào)整焦距

//調(diào)整焦距方法
-(void)focusDisdance:(UIPinchGestureRecognizer*)pinch {
     self.effectiveScale = self.beginGestureScale * pinch.scale;
    if (self.effectiveScale < 1.0f) {
        self.effectiveScale = 1.0f;
    }
    CGFloat maxScaleAndCropFactor = 3.0f;//設置最大放大倍數(shù)為3倍
    if (self.effectiveScale > maxScaleAndCropFactor)
        self.effectiveScale = maxScaleAndCropFactor;
    [CATransaction begin];
    [CATransaction setAnimationDuration:.025];
    NSError *error;
    if([self.cameraManager.inputCamera lockForConfiguration:&error]){
        [self.cameraManager.inputCamera setVideoZoomFactor:self.effectiveScale];
        [self.cameraManager.inputCamera unlockForConfiguration];
    }
    else {
        NSLog(@"ERROR = %@", error);
    }
    
    [CATransaction commit];
}

//手勢代理方法
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if ( [gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]] ) {
        self.beginGestureScale = self.effectiveScale;
    }
    return YES;
}

對焦

//對焦方法
- (void)focus:(UITapGestureRecognizer *)tap {
    self.preview.userInteractionEnabled = NO;
    CGPoint touchPoint = [tap locationInView:tap.view];
   // CGContextRef *touchContext = UIGraphicsGetCurrentContext();
    [self layerAnimationWithPoint:touchPoint];
/**
*下面是照相機焦點坐標軸和屏幕坐標軸的映射問題暴区,這個坑困惑了我好久闯团,花了各種方案來解決這個問題,以下是最簡單的解決方案也是最準確的坐標轉(zhuǎn)換方式
*/
    if(_cameraManager.cameraPosition == AVCaptureDevicePositionBack){
        touchPoint = CGPointMake( touchPoint.y /tap.view.bounds.size.height ,1-touchPoint.x/tap.view.bounds.size.width);
    }
    else
        touchPoint = CGPointMake(touchPoint.y /tap.view.bounds.size.height ,touchPoint.x/tap.view.bounds.size.width);
/*以下是相機的聚焦和曝光設置颜启,前置不支持聚焦但是可以曝光處理偷俭,后置相機兩者都支持,下面的方法是通過點擊一個點同時設置聚焦和曝光缰盏,當然根據(jù)需要也可以分開進行處理
*/
    if([self.cameraManager.inputCamera isExposurePointOfInterestSupported] && [self.cameraManager.inputCamera isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure])
    {
        NSError *error;
        if ([self.cameraManager.inputCamera lockForConfiguration:&error]) {
        [self.cameraManager.inputCamera setExposurePointOfInterest:touchPoint];
        [self.cameraManager.inputCamera setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
             if ([self.cameraManager.inputCamera isFocusPointOfInterestSupported] && [self.cameraManager.inputCamera isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
                 [self.cameraManager.inputCamera setFocusPointOfInterest:touchPoint];
                 [self.cameraManager.inputCamera setFocusMode:AVCaptureFocusModeAutoFocus];
             }
        [self.cameraManager.inputCamera unlockForConfiguration];
        } else {
            NSLog(@"ERROR = %@", error);
        }
    }
}

//對焦動畫
- (void)layerAnimationWithPoint:(CGPoint)point {
    if (_focusLayer) {
///聚焦點聚焦動畫設置
        CALayer *focusLayer = _focusLayer;
        focusLayer.hidden = NO;
        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        [focusLayer setPosition:point];
        focusLayer.transform = CATransform3DMakeScale(2.0f,2.0f,1.0f);
        [CATransaction commit];
        
        CABasicAnimation *animation = [ CABasicAnimation animationWithKeyPath: @"transform" ];
        animation.toValue = [ NSValue valueWithCATransform3D: CATransform3DMakeScale(1.0f,1.0f,1.0f)];
        animation.delegate = self;
        animation.duration = 0.3f;
        animation.repeatCount = 1;
        animation.removedOnCompletion = NO;
        animation.fillMode = kCAFillModeForwards;
        [focusLayer addAnimation: animation forKey:@"animation"];
    }
}

//動畫的delegate方法
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    //    1秒鐘延時
    [self performSelector:@selector(focusLayerNormal) withObject:self afterDelay:0.5f];
}

//focusLayer回到初始化狀態(tài)
- (void)focusLayerNormal {
    self.preview.userInteractionEnabled = YES;
    _focusLayer.hidden = YES;
}

閃光燈設置

//設置閃光燈模式

- (void)setFlashMode:(CameraManagerFlashMode)flashMode {
    _flashMode = flashMode;
    
    switch (flashMode) {
        case CameraManagerFlashModeAuto: {
            [self.cameraManager.inputCamera lockForConfiguration:nil];
            if ([self.cameraManager.inputCamera isFlashModeSupported:AVCaptureFlashModeAuto]) {
                 [self.cameraManager.inputCamera setFlashMode:AVCaptureFlashModeAuto];
            }
            [self.cameraManager.inputCamera unlockForConfiguration];
        }
            break;
        case CameraManagerFlashModeOff: {
            [self.cameraManager.inputCamera lockForConfiguration:nil];
            [self.cameraManager.inputCamera setFlashMode:AVCaptureFlashModeOff];
            [self.cameraManager.inputCamera unlockForConfiguration];
        }
            
            break;
        case CameraManagerFlashModeOn: {
            [self.cameraManager.inputCamera lockForConfiguration:nil];
            [self.cameraManager.inputCamera setFlashMode:AVCaptureFlashModeOn];
            [self.cameraManager.inputCamera unlockForConfiguration];
        }
            break;
            
        default:
            break;
    }
}


#pragma mark 改變閃光燈狀態(tài)
- (void)changeFlashMode:(UIButton *)button {
    switch (self.flashMode) {
        case CameraManagerFlashModeAuto:
            self.flashMode = CameraManagerFlashModeOn;
            [button setImage:[UIImage imageNamed:@"flashing_on"] forState:UIControlStateNormal];
            break;
        case CameraManagerFlashModeOff:
            self.flashMode = CameraManagerFlashModeAuto;
            [button setImage:[UIImage imageNamed:@"flashing_auto"] forState:UIControlStateNormal];
            break;
        case CameraManagerFlashModeOn:
            self.flashMode = CameraManagerFlashModeOff;
            [button setImage:[UIImage imageNamed:@"flashing_off"] forState:UIControlStateNormal];
            break;
            
        default:
            break;
    }
}

對拍照之后的照片進行濾鏡處理

  • 這個其實很簡單涌萤,處理方案和之前的實時濾鏡差不多,也是通過FilterController來實現(xiàn)濾鏡的選擇口猜,下面就給出選擇濾鏡之后進行處理的函數(shù)
- (void)switchCameraFilter:(NSInteger)index {
    UIImage *inputImage = self.image;
    switch (index) {
        case 0:
            _filter = [[GPUImageFilter alloc] init];//原圖
            break;
        case 1:
            _filter = [[GPUImageHueFilter alloc] init];//綠巨人
            break;
        case 2:
            _filter = [[GPUImageColorInvertFilter alloc] init];//負片
            break;
        case 3:
            _filter = [[GPUImageSepiaFilter alloc] init];//老照片
            break;
        case 4: {
            _filter = [[GPUImageGaussianBlurPositionFilter alloc] init];
            [(GPUImageGaussianBlurPositionFilter*)_filter setBlurRadius:40.0/320.0];
        }
            break;
        case 5:
            _filter = [[GPUImageMedianFilter alloc] init];
            break;
        case 6:
            _filter = [[GPUImageVignetteFilter alloc] init];//黑暈
            break;
        case 7:
            _filter = [[GPUImageKuwaharaRadius3Filter alloc] init];
            break;
        case 8:
            _filter = [[GPUImageBilateralFilter alloc] init];
        default:
            _filter = [[GPUImageFilter alloc] init];
            break;
    }
    
    //到這里為止和實時濾鏡的處理都一樣负溪,不一樣的就只有下面幾句
    [_filter forceProcessingAtSize:inputImage.size];
    [_filter useNextFrameForImageCapture];
    
    GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:inputImage smoothlyScaleOutput:YES];
    
    [stillImageSource addTarget:_filter];
    
    [stillImageSource processImage];
    
    _currentImage = [_filter imageFromCurrentFramebuffer];
//這里得到的currentImage就是添加了濾鏡之后的照片,可以放在imageView中直接顯示济炎,也可以稍加處理保存到相冊
    [self.imageView setImage:_currentImage];
}

總結(jié)

  • 以上是最近在做自定義相機時做的一點總結(jié)川抡,之前在做的時候也查閱了很多文章,感覺相對比較分散须尚,所以這里就稍微做一下整理崖堤,希望大家在做類似需求的開發(fā)時能少碰到點坑。當然我做的也不怎么完善耐床,風格也比較雜亂密幔,后續(xù)會對此做些改進。
  • 有什么不對的地方歡迎大家批評指正撩轰,共同學習
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胯甩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子堪嫂,更是在濱河造成了極大的恐慌偎箫,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皆串,死亡現(xiàn)場離奇詭異淹办,居然都是意外死亡,警方通過查閱死者的電腦和手機恶复,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門怜森,熙熙樓的掌柜王于貴愁眉苦臉地迎上來齐遵,“玉大人,你說我怎么就攤上這事塔插。” “怎么了拓哟?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵想许,是天一觀的道長。 經(jīng)常有香客問我断序,道長流纹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任违诗,我火速辦了婚禮漱凝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诸迟。我一直安慰自己茸炒,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布阵苇。 她就那樣靜靜地躺著壁公,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绅项。 梳的紋絲不亂的頭發(fā)上紊册,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音快耿,去河邊找鬼囊陡。 笑死,一個胖子當著我的面吹牛掀亥,可吹牛的內(nèi)容都是我干的撞反。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼铺浇,長吁一口氣:“原來是場噩夢啊……” “哼痢畜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鳍侣,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤丁稀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后倚聚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體线衫,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年惑折,在試婚紗的時候發(fā)現(xiàn)自己被綠了授账。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枯跑。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖白热,靈堂內(nèi)的尸體忽然破棺而出敛助,到底是詐尸還是另有隱情,我是刑警寧澤屋确,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布纳击,位于F島的核電站,受9級特大地震影響攻臀,放射性物質(zhì)發(fā)生泄漏焕数。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一刨啸、第九天 我趴在偏房一處隱蔽的房頂上張望堡赔。 院中可真熱鬧,春花似錦设联、人聲如沸善已。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽雕拼。三九已至,卻和暖如春粘招,著一層夾襖步出監(jiān)牢的瞬間啥寇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工洒扎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留辑甜,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓袍冷,卻偏偏與公主長得像磷醋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子胡诗,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

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