Android NDK開發(fā):實(shí)戰(zhàn)案例-電動車牌號識別(自定義相機(jī)及自定義遮罩控件)

目錄

相關(guān)文章

Android NDK開發(fā):實(shí)戰(zhàn)案例-電動車牌號識別(介紹)
利用PorterDuffXfermode繪制圖片文字

自定義相機(jī)

代碼展示
public class ScanningCameraView extends SurfaceView implements SurfaceHolder.Callback,Camera.PreviewCallback{
    private Camera mCamera;//相機(jī)
    private boolean isSupportAutoFocus;//是否支持自動對焦
    private int screenHeight;//屏幕的高度
    private int screenWidth;//屏幕的寬度
    private boolean isPreviewing;//是否在預(yù)覽
    private IdentifyCallBack identifyCallBack;//掃描成功的回調(diào)函數(shù)
    private boolean isScanning =false;
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1){
                if(identifyCallBack!=null){
                    identifyCallBack.onIdentifyImage((Bitmap) msg.obj);
                }
            }
        }
    };
    public ScanningCameraView(Context context) {
        super(context);
        init();
    }

    public ScanningCameraView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ScanningCameraView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
    private void init() {
        //獲取屏幕分辨率
        DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
        screenWidth = dm.heightPixels;
        screenHeight = dm.widthPixels;
        isSupportAutoFocus = getContext().getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA_AUTOFOCUS);
        getHolder().addCallback(this);
    }
    public void setIdentifyCallBack(IdentifyCallBack identifyCallBack) {
        this.identifyCallBack = identifyCallBack;
    }
    /**
     * 開燈
     */
    public void openLight(){
        Camera.Parameters parameters = mCamera.getParameters();
        //打開閃光燈
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);//開啟
        mCamera.setParameters(parameters);
    }

    /**
     * 關(guān)燈
     */
    public void closeLight(){
        Camera.Parameters parameters = mCamera.getParameters();
        //打開閃光燈
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);//開啟
        mCamera.setParameters(parameters);
    }
    /**
     * Camera幀數(shù)據(jù)回調(diào)用
     */
    @Override
    public void onPreviewFrame(final byte[] data, final Camera camera) {
        camera.addCallbackBuffer(data);
        new Thread(new Runnable() {
            @Override
            public void run() {
                //識別中不處理其他幀數(shù)據(jù)
                if (!isScanning) {
                    isScanning = true;
                    try {
                        //獲取Camera預(yù)覽尺寸
                        Camera.Size size = camera.getParameters().getPreviewSize();
                        //將幀數(shù)據(jù)轉(zhuǎn)為bitmap
                        YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
                        if (image != null) {
                            ByteArrayOutputStream stream = new ByteArrayOutputStream();
                            image.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, stream);
                            Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
                            Bitmap bitmap = cutImage(bmp);//獲取遮罩處圖像
                            Message message = handler.obtainMessage();
                            message.what = 1;
                            message.obj = bitmap;
                            handler.sendMessage(message);
                            isScanning = false;
                        }
                    } catch (Exception ex) {
                        isScanning = false;
                    }
                }
            }
        }
        ).start();

    }
    /**
     * 攝像頭自動聚焦
     */
    Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
        public void onAutoFocus(boolean success, Camera camera) {
            postDelayed(doAutoFocus, 500);
        }
    };
    private Runnable doAutoFocus = new Runnable() {
        public void run() {
            if (mCamera != null) {
                try {
                    mCamera.autoFocus(autoFocusCB);
                } catch (Exception e) {
                }
            }
        }
    };
    /**
     * 裁剪照片
     *
     * @return
     */
    private Bitmap cutImage(Bitmap bitmap) {
        int h = bitmap.getWidth();
        int w = bitmap.getHeight();
        int clipw = w/5*3;//這里根據(jù)遮罩的比例進(jìn)行裁剪
        int cliph = (int) (clipw*1.93f);
        int x = (w - clipw) / 2;
        int y = (h - cliph) / 2;
        return Bitmap.createBitmap(bitmap, y, x,cliph, clipw);
    }
    /**
     * 打開指定攝像頭
     */
    public void openCamera() {
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        for (int cameraId = 0; cameraId < Camera.getNumberOfCameras(); cameraId++) {
            Camera.getCameraInfo(cameraId, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                try {
                    mCamera = Camera.open(cameraId);
                } catch (Exception e) {
                    if (mCamera != null) {
                        mCamera.release();
                        mCamera = null;
                    }
                }
                break;
            }
        }
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            releaseCamera();
            openCamera();
            initCamera();
        }catch (Exception e){
            mCamera = null;
        }
    }

    /**
     * 加載相機(jī)配置
     */
    private void initCamera() {
        try {
            mCamera.setPreviewDisplay(getHolder());//當(dāng)前控件顯示相機(jī)數(shù)據(jù)
            mCamera.setDisplayOrientation(90);//調(diào)整預(yù)覽角度
            setCameraParameters();
            startPreview();//打開相機(jī)
        }catch (Exception e){
            releaseCamera();
        }
    }

    /**
     * 配置相機(jī)參數(shù)
     */
    private void setCameraParameters() {
        Camera.Parameters parameters = mCamera.getParameters();
        List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
        double scale = (double) getWidth() / getHeight();
        Camera.Size cameraSize = SortCameraSizeUtil.getCameraSize(sizes, scale);
        if(cameraSize != null){
            screenWidth = cameraSize.width;
            screenHeight = cameraSize.height;
        }else {
            //確定前面定義的預(yù)覽寬高是camera支持的,不支持取就更大的
            for (int i = 0; i < sizes.size(); i++) {
                if ((sizes.get(i).width >= screenWidth && sizes.get(i).height >= screenHeight) || i == sizes.size() - 1) {
                    screenWidth = sizes.get(i).width;
                    screenHeight = sizes.get(i).height;
                    break;
                }
            }
        }
        //設(shè)置最終確定的預(yù)覽大小
        parameters.setPreviewSize(screenWidth, screenHeight);//設(shè)置預(yù)覽分辨率
        parameters.setPictureSize(screenWidth, screenHeight);//設(shè)置拍照圖片的分辨率
        mCamera.setParameters(parameters);
    }
    /**
     * 釋放相機(jī)
     */
    private void releaseCamera() {
        if(mCamera!=null){
            stopPreview();
            mCamera.setPreviewCallback(null);
            mCamera.release();
            mCamera=null;
        }
    }
    /**
     * 停止預(yù)覽
     */
    private void stopPreview() {
        if (mCamera != null && isPreviewing) {
            mCamera.stopPreview();
            isPreviewing = false;
        }
    }

    /**
     * 開始預(yù)覽
     */
    public void startPreview() {
        if (mCamera != null) {
            mCamera.addCallbackBuffer(new byte[((screenWidth * screenHeight) * ImageFormat.getBitsPerPixel(ImageFormat.NV21)) / 8]);
            mCamera.setPreviewCallbackWithBuffer(this);
            mCamera.startPreview();
            if(isSupportAutoFocus) {
                mCamera.autoFocus(autoFocusCB);
            }
            isPreviewing = true;
        }
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        stopPreview();
        initCamera();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        releaseCamera();
    }
    public interface IdentifyCallBack{
        /**
         * 回調(diào)掃描的車牌區(qū)域
         */
        void onIdentifyImage(Bitmap bitmap);
    }
}

重點(diǎn)講解

●調(diào)整預(yù)覽角度
如果不進(jìn)行預(yù)覽角度的調(diào)整,自定義相機(jī)展現(xiàn)的畫面會是橫著的琐脏,因此需要將角度旋轉(zhuǎn)90度杨名。

mCamera.setDisplayOrientation(90);//調(diào)整預(yù)覽角度

●獲取最佳比例的分辨率
這里是根據(jù)這個(gè)自定義相機(jī)控件的寬高比與相機(jī)支持的各個(gè)分辨率的寬高比對比來進(jìn)行篩選的香罐,找到那個(gè)差值最小的分辨率即可科雳,代碼如下:

 /**
     * 配置相機(jī)參數(shù)
     */
    private void setCameraParameters() {
        Camera.Parameters parameters = mCamera.getParameters();
        //獲取相機(jī)支持的分辨率
        List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
        //自定義相機(jī)控件的寬高比
        double scale = (double) getWidth() / getHeight();
        //通過對比取出差值最小的那個(gè)分辨率
        Camera.Size cameraSize = SortCameraSizeUtil.getCameraSize(sizes, scale);
        if(cameraSize != null){
            screenWidth = cameraSize.width;
            screenHeight = cameraSize.height;
        }else {
            //如果找不到就取一個(gè)最清晰的
            //確定前面定義的預(yù)覽寬高是camera支持的,不支持取就更大的
            for (int i = 0; i < sizes.size(); i++) {
                if ((sizes.get(i).width >= screenWidth && sizes.get(i).height >= screenHeight) || i == sizes.size() - 1) {
                    screenWidth = sizes.get(i).width;
                    screenHeight = sizes.get(i).height;
                    break;
                }
            }
        }
        //設(shè)置最終確定的預(yù)覽大小
        parameters.setPreviewSize(screenWidth, screenHeight);//設(shè)置預(yù)覽分辨率
        parameters.setPictureSize(screenWidth, screenHeight);//設(shè)置拍照圖片的分辨率
        mCamera.setParameters(parameters);
    }
 /**
     * 返回寬高比差值最小的Size
     * @param sizes 系統(tǒng)支持的Camera的Size
     * @param showViewRatio 當(dāng)前自定義的相機(jī)控件展示的寬高的比值
     * @return
     */
    public static Camera.Size getCameraSize(List<Camera.Size> sizes,double showViewRatio){
        ArrayList<CameraSizeBean> sortSizeBeans = new ArrayList<>();
        for (Camera.Size size : sizes) {
            if(size != null){
                //獲取當(dāng)前遍歷到的分辨率的寬高比(注意由于相機(jī)的角度問題衬鱼,這里是高比寬)
                double scale = (double) size.height / size.width;
                //獲取到兩個(gè)比值的差值的絕對值并存儲起來
                sortSizeBeans.add(new CameraSizeBean(size,Math.abs(showViewRatio - scale)));
            }
        }
        //對集合進(jìn)行排序买喧,差值最小的排上面
        Collections.sort(sortSizeBeans);
        if(sortSizeBeans.size() > 0){
            //將差值最小的返回
            return sortSizeBeans.get(0).getSize();
        }else {
            return null;
        }
    }

●自定義相機(jī)幀數(shù)據(jù)的回調(diào)
由于我們實(shí)現(xiàn)的是掃描識別并不是拍照識別捻悯,因此我們需要獲取相機(jī)的每一幀圖像,并進(jìn)行處理淤毛,這就需要我們進(jìn)行相應(yīng)的配置今缚,代碼如下:

mCamera.addCallbackBuffer(new byte[((screenWidth * screenHeight) * ImageFormat.getBitsPerPixel(ImageFormat.NV21)) / 8]);
mCamera.setPreviewCallbackWithBuffer(this);

回調(diào)函數(shù)如下:

/**
     * Camera幀數(shù)據(jù)回調(diào)用
     */
    @Override
    public void onPreviewFrame(final byte[] data, final Camera camera) {
        camera.addCallbackBuffer(data);
        new Thread(new Runnable() {
            @Override
            public void run() {
                //識別中不處理其他幀數(shù)據(jù)
                if (!isScanning) {
                    isScanning = true;
                    try {
                        //獲取Camera預(yù)覽尺寸
                        Camera.Size size = camera.getParameters().getPreviewSize();
                        //將幀數(shù)據(jù)轉(zhuǎn)為bitmap
                        YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
                        if (image != null) {
                            ByteArrayOutputStream stream = new ByteArrayOutputStream();
                            image.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, stream);
                            Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
                            Bitmap bitmap = cutImage(bmp);//獲取遮罩處圖像
                            Message message = handler.obtainMessage();
                            message.what = 1;
                            message.obj = bitmap;
                            handler.sendMessage(message);
                            isScanning = false;
                        }
                    } catch (Exception ex) {
                        isScanning = false;
                    }
                }
            }
        }
        ).start();

    }

自定義遮罩

代碼展示
public class ScanningMaskView extends View {
    private float mMaskWidth;//中間透明部分的寬度
    private float mMaskHeight;//中間透明部分的高度
    private Paint mPaintMask;//遮罩畫筆
    private Paint mPaintText;//文字畫筆
    private Paint mPaintMaskStrok;//遮罩描邊畫筆
    private float mTextSize = 30;//文字大小
    private Path mMaskPath;//遮罩透明部分路徑
    private String mTopTripStr = "請掃描電動車牌號";
    private String mBottomTripStr = "請保持光線充足";

    public ScanningMaskView(Context context) {
        super(context);
        init();
    }

    public ScanningMaskView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ScanningMaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /**
     * 當(dāng)控件大小改變的時(shí)候動態(tài)調(diào)整遮罩的大小
     * @param w
     * @param h
     * @param oldw
     * @param oldh
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mMaskWidth = w/5*3;//遮罩透明部分的寬度為控件寬度的3/5
        mMaskHeight = mMaskWidth*1.93f;//遮罩透明部分的高度根據(jù)車牌比例算出
        mMaskPath.reset();
        mTextSize = w/20;
        mPaintText.setTextSize(mTextSize);//設(shè)置文字大小
        float left = (w-mMaskWidth)/2;
        float top = (h-mMaskHeight)/2;
        float right = left + mMaskWidth;
        float bottom = top + mMaskHeight;
        mMaskPath.addRoundRect(new RectF(left,top,right,bottom),10,10, Path.Direction.CW);
        invalidate();
    }
    private void init(){
        //關(guān)閉硬件加速
        setLayerType(LAYER_TYPE_SOFTWARE,null);

        mPaintMask = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintMask.setStyle(Paint.Style.FILL);
        mPaintMask.setColor(Color.BLACK);
        mPaintMask.setAlpha(160);//設(shè)置半透明

        mPaintText = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintText.setStrokeWidth(3);
        mPaintText.setColor(Color.WHITE);//設(shè)置文字顏色
        mPaintText.setTextAlign(Paint.Align.CENTER);//文字水平居中

        mPaintMaskStrok = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintMaskStrok.setColor(Color.WHITE);
        mPaintMaskStrok.setStyle(Paint.Style.STROKE);
        mPaintMaskStrok.setStrokeWidth(3);

        mMaskPath = new Path();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();//離屏繪制
        canvas.drawRect(0,0,getWidth(),getHeight(),mPaintMask);//繪制整個(gè)控件大小遮罩
        mPaintMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));//將透明部分摳出來
        canvas.drawPath(mMaskPath,mPaintMask);
        mPaintMask.setXfermode(null);//清除混合模式
        canvas.restore();
        canvas.drawPath(mMaskPath,mPaintMaskStrok);//繪制遮罩描邊
        canvas.save();
        canvas.translate(getWidth()/2,getHeight()/2);
        canvas.rotate(90);//旋轉(zhuǎn)90度繪制文字
        canvas.drawText(mTopTripStr,0,-((mMaskWidth/2)+((getWidth()-mMaskWidth)/4)),mPaintText);
        canvas.drawText(mBottomTripStr,0,(mMaskWidth/2)+((getWidth()-mMaskWidth)/4),mPaintText);
        canvas.restore();
    }
}

重點(diǎn)講解

●遮罩透明部分
遮罩透明部分主要是用了混合模式來實(shí)現(xiàn)的,具體就不多做解釋了低淡,這里我有一個(gè)小案例:利用PorterDuffXfermode繪制圖片文字姓言,想了解的同學(xué)可以點(diǎn)一下看看,或是自己百度了解下也可以蔗蹋。
●透明部分比例


透明部分的比例何荚,以豎著的方式來看,寬度為屏幕寬度的3/5纸颜,高度為寬度的1.93倍兽泣,這個(gè)1.93并不是隨便寫的數(shù)據(jù)绎橘,而是因?yàn)?.93差不多也是電動車牌的寬高比胁孙,對應(yīng)代碼如下:

mMaskWidth = w/5*3;//遮罩透明部分的寬度為控件寬度的3/5
mMaskHeight = mMaskWidth*1.93f;//遮罩透明部分的高度根據(jù)車牌比例算出

●車牌號區(qū)域裁剪
車牌號部分的裁剪其實(shí)就是遮罩透明區(qū)域的裁剪,既然我們知道了透明部分區(qū)域的計(jì)算方式那么裁剪就很簡單了称鳞,這部分代碼在自定義相機(jī)里涮较,代碼如下:

   /**
     * 裁剪照片
     *
     * @return
     */
    private Bitmap cutImage(Bitmap bitmap) {
        int h = bitmap.getWidth();
        int w = bitmap.getHeight();
        int clipw = w/5*3;//這里根據(jù)遮罩的比例進(jìn)行裁剪
        int cliph = (int) (clipw*1.93f);
        int x = (w - clipw) / 2;
        int y = (h - cliph) / 2;
        return Bitmap.createBitmap(bitmap, y, x,cliph, clipw);
    }

掃描動畫實(shí)現(xiàn)

掃描動畫我是使用TranslateAnimation來實(shí)現(xiàn)的,就是利用TranslateAnimation使掃描線從豎著的方向來看從右向左移動冈止,到底之后就反轉(zhuǎn)執(zhí)行動畫狂票,而那條線就是背景為橢圓shape的View拉長之后看著就像中間粗兩邊細(xì)的線,代碼如下:

/**
     * 動畫設(shè)置
     */
    void setAnimation() {
        TranslateAnimation mAnimation = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT, 0.99f,TranslateAnimation.RELATIVE_TO_PARENT, 0.01f,TranslateAnimation.ABSOLUTE, 0f,TranslateAnimation.ABSOLUTE,0f);
        mAnimation.setDuration(5000);
        mAnimation.setRepeatMode(Animation.REVERSE);// 設(shè)置反方向執(zhí)行
        mAnimation.setRepeatCount(Animation.INFINITE);
        viewScanningline.setAnimation(mAnimation);
        mAnimation.start();
    }

而執(zhí)行動畫的區(qū)域是使用了百分百布局來進(jìn)行固定的熙暴,使其移動的軌跡剛好在遮罩透明區(qū)域闺属,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.itfitness.licenseocrdemo.widget.camera.ScanningCameraView
        android:id="@+id/camera2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    <com.itfitness.licenseocrdemo.widget.mask.ScanningMaskView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    <!--掃描線的區(qū)域-->
    <RelativeLayout
        android:id="@+id/layout_scanning"
        app:layout_aspectRatio="51.90%"
        app:layout_widthPercent="60%"
        android:layout_centerInParent="true">
        <!--掃描線-->
        <View
            android:id="@+id/view_scanningline"
            android:layout_alignParentLeft="true"
            android:background="@drawable/shape_scanningline"
            android:layout_width="2dp"
            android:layout_height="match_parent"/>
    </RelativeLayout>
    <ImageView
        android:id="@+id/img"
        android:scaleType="centerInside"
        android:layout_width="wrap_content"
        android:layout_height="90dp"
        />
    <ImageView
        android:id="@+id/img_light"
        android:layout_centerHorizontal="true"
        app:layout_marginTopPercent="86%"
        android:rotation="90"
        android:background="@drawable/selector_light"
        app:layout_aspectRatio="120%"
        app:layout_widthPercent="15%"
        />
</android.support.percent.PercentRelativeLayout>

實(shí)現(xiàn)效果

注意事項(xiàng)

●權(quán)限問題
別忘了權(quán)限的添加:

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

另外如果是Android6.0及以上別忘了動態(tài)申請權(quán)限,這里我為了省事所以沒進(jìn)行動態(tài)申請而是直接手動開啟的權(quán)限周霉。
●項(xiàng)目類型
我這里創(chuàng)建的是Native C++項(xiàng)目

案例源碼

https://gitee.com/itfitness/LicenseOcrDemo

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掂器,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子俱箱,更是在濱河造成了極大的恐慌国瓮,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異乃摹,居然都是意外死亡禁漓,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進(jìn)店門孵睬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來播歼,“玉大人,你說我怎么就攤上這事掰读〖远瘢” “怎么了?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵磷支,是天一觀的道長谒撼。 經(jīng)常有香客問我,道長雾狈,這世上最難降的妖魔是什么廓潜? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮善榛,結(jié)果婚禮上辩蛋,老公的妹妹穿的比我還像新娘。我一直安慰自己移盆,他們只是感情好悼院,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咒循,像睡著了一般据途。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上叙甸,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天颖医,我揣著相機(jī)與錄音,去河邊找鬼裆蒸。 笑死熔萧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的僚祷。 我是一名探鬼主播佛致,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼辙谜!你這毒婦竟也來了俺榆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤筷弦,失蹤者是張志新(化名)和其女友劉穎肋演,沒想到半個(gè)月后抑诸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爹殊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年蜕乡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梗夸。...
    茶點(diǎn)故事閱讀 38,683評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡层玲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出反症,到底是詐尸還是另有隱情辛块,我是刑警寧澤,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布铅碍,位于F島的核電站润绵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏胞谈。R本人自食惡果不足惜尘盼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烦绳。 院中可真熱鬧卿捎,春花似錦、人聲如沸径密。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽享扔。三九已至底桂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伪很,已是汗流浹背戚啥。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锉试,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓览濒,卻偏偏與公主長得像呆盖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子贷笛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評論 2 349

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