Android平臺(tái)下的圖片/視頻轉(zhuǎn)Ascii碼圖片/視頻 (一) (github持續(xù)更新)

????前一陣看鴻洋公眾號(hào)日推摆寄,看到一個(gè)幾年前就感覺(jué)有意思的一個(gè)技術(shù),那就是圖片轉(zhuǎn)Ascii碼,記得上大學(xué)時(shí)玩過(guò)windows的圖片或視頻轉(zhuǎn)ascii碼排截,可惜那個(gè)軟件不好用,有bug辐益,轉(zhuǎn)視頻的時(shí)候動(dòng)不動(dòng)就卡死断傲,5分鐘的視頻,轉(zhuǎn)碼百分之7智政,8十的時(shí)候有一半概率卡死- -认罩,總有意猶未盡的感覺(jué)。

????去年的時(shí)候续捂,自己從java移植過(guò)一種算法到android垦垂,大概思路如下:首先固定字號(hào),然后計(jì)算這個(gè)字號(hào)下繪制出一個(gè)字母需要的像素(長(zhǎng)x寬)牙瓢,然后對(duì)于圖片:取出同等大小的圖片碎片劫拗,然后列出每一個(gè)備選的字母繪制出來(lái)以后的像素rgb值(一般是ascii碼,當(dāng)然也可以是漢字矾克,不過(guò)肯定效果不好)页慷,計(jì)算每個(gè)替換字的rgb轉(zhuǎn)灰色像素?cái)?shù)組 相對(duì) 圖片碎片像素?cái)?shù)組的標(biāo)準(zhǔn)差(還有幾個(gè)備選算法不記得了,這不是重點(diǎn)~),標(biāo)準(zhǔn)差最小的胁附,作為圖片碎片的替換字酒繁。最后像國(guó)際象棋格子一樣,一塊一塊的替換掉控妻,由于計(jì)算相對(duì)比較復(fù)雜州袒,所以耗時(shí)比較長(zhǎng),因此當(dāng)時(shí)那個(gè)demo也讓我擱置了弓候。最近看到這篇日推郎哭,不由得眼前一亮他匪,因?yàn)楹苌儆腥嗽赼ndroid端做這種東西,因?yàn)樗惴ǚ桨甘且淮蠖芽溲校贿^(guò)很少有感興趣的人去移植到android- -邦蜜,我就參考了這篇文章的方案,不由得贊嘆這個(gè)方法的巧妙陈惰,避免了大量的計(jì)算畦徘,圖片轉(zhuǎn)化率大大提高了,可以看看效果圖 :


ccg和修政

????哈哈哈抬闯,是不是很酷炫井辆?為了看清每一個(gè)字母,特意上傳了一個(gè)大圖(ps:抖音上竟然有人手動(dòng)敲的ascii碼溶握,而且敲了幾天杯缺,真是喪心病狂)。好了睡榆,下面進(jìn)入正題~

????巧婦難為無(wú)米之炊萍肆,既然要圖片/視頻轉(zhuǎn)化 ascii碼,要有對(duì)應(yīng)的媒體文件胀屿,選擇一個(gè)圖片塘揣,相信每一個(gè)android開(kāi)發(fā)者都或多或少有個(gè)趁手的圖片選擇庫(kù),這里使用了 'com.github.LuckSiege.PictureSelector:picture_library:v2.2.3'宿崭,持續(xù)更新的庫(kù)亲铡,比較好用。
????用法大概如下~

public static void choosePhoto(Activity context, int requestCode) {
        PictureSelector.create(context)
                .openGallery(PictureMimeType.ofAll())//全部.PictureMimeType.ofAll()葡兑、圖片.ofImage()奖蔓、視頻.ofVideo()、音頻.ofAudio()
//                .theme()//主題樣式(不設(shè)置為默認(rèn)樣式) 也可參考demo values/styles下 例如:R.style.picture.white.style
                .maxSelectNum(1)// 最大圖片選擇數(shù)量 int
//                .minSelectNum()// 最小選擇數(shù)量 int
                .imageSpanCount(4)// 每行顯示個(gè)數(shù) int
                .selectionMode(PictureConfig.SINGLE)// 多選 or 單選 PictureConfig.MULTIPLE or PictureConfig.SINGLE
//                .previewImage()// 是否可預(yù)覽圖片 true or false
//                .previewVideo()// 是否可預(yù)覽視頻 true or false
//                .enablePreviewAudio() // 是否可播放音頻 true or false
                .isCamera(true)// 是否顯示拍照按鈕 true or false
                .imageFormat(PictureMimeType.PNG)// 拍照保存圖片格式后綴,默認(rèn)jpeg
                .isZoomAnim(true)// 圖片列表點(diǎn)擊 縮放效果 默認(rèn)true
                .sizeMultiplier(0.5f)// glide 加載圖片大小 0~1之間 如設(shè)置 .glideOverride()無(wú)效
//                .setOutputCameraPath("/CustomPath")// 自定義拍照保存路徑,可不填
//                .enableCrop(true)// 是否裁剪 true or false
//                .compress(false)// 是否壓縮 true or false
//                .glideOverride()// int glide 加載寬高讹堤,越小圖片列表越流暢吆鹤,但會(huì)影響列表圖片瀏覽的清晰度
//                .withAspectRatio(1, 1)// int 裁剪比例 如16:9 3:2 3:4 1:1 可自定義
//                .hideBottomControls()// 是否顯示uCrop工具欄,默認(rèn)不顯示 true or false
//                .isGif()// 是否顯示gif圖片 true or false
//                .compressSavePath(context.getFilesDir().getAbsolutePath())//壓縮圖片保存地址
//                .freeStyleCropEnabled(true)// 裁剪框是否可拖拽 true or false
//                .circleDimmedLayer(true)// 是否圓形裁剪 true or false
//                .showCropFrame(false)// 是否顯示裁剪矩形邊框 圓形裁剪時(shí)建議設(shè)為false   true or false
//                .showCropGrid(false)// 是否顯示裁剪矩形網(wǎng)格 圓形裁剪時(shí)建議設(shè)為false    true or false
                .openClickSound(true)// 是否開(kāi)啟點(diǎn)擊聲音 true or false
//                .selectionMedia()// 是否傳入已選圖片 List<LocalMedia> list
//                .previewEggs()// 預(yù)覽圖片時(shí) 是否增強(qiáng)左右滑動(dòng)圖片體驗(yàn)(圖片滑動(dòng)一半即可看到上一張是否選中) true or false
//                .cropCompressQuality(90)// 裁剪壓縮質(zhì)量 默認(rèn)90 int
                .minimumCompressSize(500)// 小于100kb的圖片不壓縮
//                .synOrAsy(true)//同步true或異步false 壓縮 默認(rèn)同步
//                .cropWH()// 裁剪寬高比洲守,設(shè)置如果大于圖片本身寬高則無(wú)效 int
//                .rotateEnabled() // 裁剪是否可旋轉(zhuǎn)圖片 true or false
//                .scaleEnabled(true)// 裁剪是否可放大縮小圖片 true or false
//                .videoQuality()// 視頻錄制質(zhì)量 0 or 1 int
//                .videoMaxSecond(15)// 顯示多少秒以?xún)?nèi)的視頻or音頻也可適用 int
//                .videoMinSecond(10)// 顯示多少秒以?xún)?nèi)的視頻or音頻也可適用 int
//                .recordVideoSecond()//視頻秒數(shù)錄制 默認(rèn)60s int
//                .isDragFrame(false)// 是否可拖動(dòng)裁剪框(固定)
                .forResult(requestCode);//結(jié)果回調(diào)onActivityResult code
    }

????接著進(jìn)行下一步操作疑务,上代碼:

public static Bitmap createAsciiPic(final String path, Context context) {
        final String base = "#8XOHLTI)i=+;:,.";// 字符串由復(fù)雜到簡(jiǎn)單
//        final String base = "#,.0123456789:;@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";// 字符串由復(fù)雜到簡(jiǎn)單
        StringBuilder text = new StringBuilder();
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        int width = dm.widthPixels;
        int height = dm.heightPixels;
        Bitmap image = BitmapFactory.decodeFile(path);  //讀取圖片
        int width0 = image.getWidth();
        int height0 = image.getHeight();
        int width1, height1;
        int scale = 7;
        if (width0 <= width / scale) {
            width1 = width0;
            height1 = height0;
        } else {
            width1 = width / scale;
            height1 = width1 * height0 / width0;
        }
        image = scale(path, width1, height1);  //讀取圖片
        //輸出到指定文件中
        for (int y = 0; y < image.getHeight(); y += 2) {
            for (int x = 0; x < image.getWidth(); x++) {
                final int pixel = image.getPixel(x, y);
                final int r = (pixel & 0xff0000) >> 16, g = (pixel & 0xff00) >> 8, b = pixel & 0xff;
                final float gray = 0.299f * r + 0.578f * g + 0.114f * b;
                final int index = Math.round(gray * (base.length() + 1) / 255);
                String s = index >= base.length() ? " " : String.valueOf(base.charAt(index));
                text.append(s);
            }
            text.append("\n");
        }
        return textAsBitmap(text, context);
//        return image;
    }

????我來(lái)說(shuō)下代碼的意義~
????首先會(huì)得到屏幕寬高,接著正規(guī)操作岖沛,對(duì)圖片進(jìn)行縮放暑始,如果圖片大小過(guò)大,就對(duì)圖片進(jìn)行縮放婴削,最大是屏幕的1/7,接著就是for循環(huán)嵌套長(zhǎng)寬,這里為什么y是y+=2呢牙肝?因?yàn)閍scii碼一般都比較長(zhǎng)吧~唉俗,按照android的標(biāo)準(zhǔn)來(lái)看ascii碼繪制出來(lái)的效果比較長(zhǎng)嗤朴。
????我們看for循環(huán)里面做了什么:對(duì)拿到的每個(gè)像素點(diǎn)進(jìn)行灰度轉(zhuǎn)化,這里就用到圖像學(xué)的知識(shí)了虫溜,為什么是0.229:0.578:0.114呢雹姊?因?yàn)閾?jù)研究(不是我研究的~),按照這樣的配比rgb轉(zhuǎn)化以后,人眼看到的是灰度圖像衡楞。吱雏。。瘾境。歧杏。開(kāi)個(gè)玩笑,這就是rgb轉(zhuǎn)灰度的公式之一迷守。然后根據(jù)灰度值犬绒,在0到255之間的位置,來(lái)配對(duì)應(yīng)的ascii碼兑凿,這里 final String base = "#8XOHLTI)i=+;:,.";(字符串由復(fù)雜到簡(jiǎn)單) 所謂的簡(jiǎn)單到復(fù)雜其實(shí)想的不用那么復(fù)雜凯力,就是相同體積內(nèi),繪制出這些字母礼华,哪一個(gè)黑色像素更多咐鹤,僅此而已。直到遍歷所有的像素點(diǎn)以后圣絮,拼成一個(gè)Stringbuffer祈惶,這里每次讀取一個(gè)width的像素以后都要加上一個(gè)換行以區(qū)分一行。接著放到一個(gè)text轉(zhuǎn)bitmap的方法里:

public static Bitmap textAsBitmap(StringBuilder text, Context context) {

        TextPaint textPaint = new TextPaint();

// textPaint.setARGB(0x31, 0x31, 0x31, 0);

        textPaint.setColor(Color.BLACK);
        textPaint.setAntiAlias(true);
        textPaint.setTypeface(Typeface.MONOSPACE);
        textPaint.setTextSize(12);
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        int width = dm.widthPixels;
        StaticLayout layout = new StaticLayout(text, textPaint, width,
        Layout.Alignment.ALIGN_CENTER, 1f, 0.0f, true);
        Bitmap bitmap = Bitmap.createBitmap(layout.getWidth() + 20,
        layoutgetHeight() + 20, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.translate(10, 10);
       canvas.drawColor(Color.WHITE);
//        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);//繪制透明色
        layout.draw(canvas);
        Log.d("textAsBitmap",      String.format("1:%d %d", layout.getWidth(), layout.getHeight()));
        return bitmap;
    }

????這里用到了StaticLayout去繪制文字晨雳,textpaint 設(shè)置單間隔的文字,設(shè)置好參數(shù)以后行瑞,在canvas上繪制,通過(guò)bitmap初始化的canvas餐禁,其實(shí)也會(huì)反應(yīng)在bitmap上血久。(我一年前應(yīng)該是沒(méi)設(shè)置好這樣的參數(shù),所以當(dāng)時(shí)畫(huà)出來(lái)的ascii碼圖片帮非,文字間隔比較大氧吐,當(dāng)時(shí)就棄坑了)得到bitmap以后,可以顯示在界面上了末盔,也可以輸出到文字里筑舅,對(duì)于圖片轉(zhuǎn)ascii碼的步驟就到此為止了。

接下來(lái)是視頻轉(zhuǎn)ascii碼的步驟:

其實(shí)視頻可看做是一幀一幀的圖片陨舱,那么接下來(lái)的思路就清晰了吧~
????首先將視頻抓幀翠拣,可以按照你設(shè)定好的每秒抓多少幀,這樣得到一堆圖像序列,而這里得到視頻幀用到了android原生的api游盲,需要android5.0以上:MediaMetadataRetriever 這個(gè)類(lèi)可以得到視頻的時(shí)長(zhǎng)误墓,以及第多少毫秒的圖片預(yù)覽幀蛮粮,于是我先拿到視頻的時(shí)長(zhǎng),比如10000毫秒谜慌,也就是10秒然想,那么接下來(lái)如果我每秒要取15張圖片,那么就每(1000/15)毫秒取一張預(yù)覽幀欣范,直到10000毫秒為止变泄,首先需要強(qiáng)調(diào)下,這個(gè)操作是十分耗時(shí)的恼琼,因此必須將這個(gè)操作放到線程里將這些圖片保存到一個(gè)路徑下妨蛹,具體代碼如下(MediaDecoder是對(duì)于MediaMetadataRetriever 稍微封裝了一下)

@Override
    public void run() {
        mediaDecoder = new MediaDecoder(path);
        String videoFileLength = mediaDecoder.getVideoFileLength();
        if (videoFileLength != null) {
            try {
                int length = Integer.parseInt(videoFileLength);
                encodeTotalCount = length / (1000 / fps);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        for (int i = 0; i < encodeTotalCount; i++) {
            Log.i("icv", "第" + i + "張解碼開(kāi)始----------------\n");
            Bitmap bitmap = mediaDecoder.decodeFrame(i * (1000 / fps));
            if (bitmap == null) continue;
            Log.i("icv", "第" + i + "張解碼結(jié)束\n");
            Log.i("icv", "第" + i + "張轉(zhuǎn)換開(kāi)始\n");
            if (weakReference == null || weakReference.get() == null) return;
            bitmapTemp = CommonUtil.createAsciiPic(bitmap, weakReference.get());
            Log.i("icv", "第" + i + "張轉(zhuǎn)換結(jié)束\n");     
            FileOutputStream fos;
            try {
                String format = String.format("%05d", i);
                fos = new FileOutputStream(MainActivity.picListPath + File.separator + "test" + format + ".png", false);
                bitmapTemp.compress(Bitmap.CompressFormat.PNG, 100, fos);
                fos.flush();
                fos.close();
                if (onEncoderListener != null) {
                    onEncoderListener.onProgress(((int) (100 * ((float) i / encodeTotalCount))));
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (onEncoderListener != null) {
                        onEncoderListener.showImg(bitmapTemp);
                    }
                }
            });
        }
        Log.i("icv", "處理完成");
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (onEncoderListener != null) {
                    onEncoderListener.onComplish();
                }
            }
        });

    }

????這里我直接保存的轉(zhuǎn)換成ascii碼圖片之后的文件了,圖片轉(zhuǎn)ascii碼的步驟見(jiàn)文章上半部分
????接下來(lái)就是最后一步了驳癌,將分割轉(zhuǎn)換的圖片再合成成視頻滑燃,合成視頻的方法我網(wǎng)上也找了很多,不過(guò)基本都是2個(gè)方式:第一個(gè)就是javacodec這個(gè)庫(kù)颓鲜,可是這個(gè)庫(kù)發(fā)現(xiàn)控制不了幀率表窘,也就是說(shuō)一個(gè)視頻如果你轉(zhuǎn)化成圖片設(shè)置的fps比較少的話,比如fps=5甜滨,那么合成視頻的時(shí)候乐严,他會(huì)按照f(shuō)ps = 25默認(rèn)的去合成視頻,那么會(huì)出現(xiàn)的問(wèn)題就是合成的視頻的播放速度會(huì)是原先的5倍- -衣摩,當(dāng)然也可以改這個(gè)庫(kù)的源碼昂验,不過(guò)因?yàn)檫@個(gè)項(xiàng)目以后還有可能加其他的好玩的功能,于是選擇了第二種方案:用ffmpeg進(jìn)行合成艾扮,ffmpeg是一個(gè)用c寫(xiě)的跨平臺(tái)的視頻處理庫(kù)既琴,里面包含了強(qiáng)大的,視頻編解碼泡嘴,推流甫恩,加水印,濾鏡等強(qiáng)大的功能酌予,這也是我選擇它的原因磺箕,由于編譯ffmpeg也是個(gè)大坑,所以直接拿來(lái)了別人編好的移植過(guò)來(lái)了抛虫。
????這里使用了ffmpeg庫(kù)里ffmpeg.c的run方法去跑你拼接的命令松靡,他也是通過(guò)java層傳遞過(guò)來(lái)一個(gè)數(shù)組,這個(gè)數(shù)組裝有ffmpeg的要執(zhí)行的命令建椰,再傳到j(luò)ni里雕欺,在這里面變成一個(gè)char數(shù)組傳遞到ffmpeg的run方法,,jni文件如下:

JNIEXPORT jint JNICALL Java_codepig_ffmpegcldemo_FFmpegKit_run
(JNIEnv *env, jclass obj, jobjectArray commands){
    //FFmpeg av_log() callback
    int argc = (*env)->GetArrayLength(env, commands);
    char *argv[argc];

    LOGD("Kit argc %d\n", argc);
    int i;
    for (i = 0; i < argc; i++) {
        jstring js = (jstring) (*env)->GetObjectArrayElement(env, commands, i);
        argv[i] = (char*) (*env)->GetStringUTFChars(env, js, 0);
        LOGD("Kit argv %s\n", argv[i]);
    }
    return run(argc, argv);
}
????而java拼成ffmpeg的命令的方法如下:
    public static String[] concatVideo(String _filePath, String _outPath,String fps) {//-f concat -i list.txt -c copy concat.mp4
        ArrayList<String> _commands = new ArrayList<>();

        {

            _commands.add("ffmpeg");
            _commands.add("-f");
            _commands.add("image2");
            _commands.add("-framerate");
            _commands.add(fps);
            _commands.add("-i");
            _commands.add(_filePath+"/test%05d.png");
//            _commands.add("-filter_complex");
//            _commands.add("[1:v]scale=1920:1080[s];[0:v][s]overlay=0:0");
            _commands.add("-b");
            _commands.add("1000k");
//            _commands.add("-s");
//            _commands.add("640x360");
            _commands.add("-ss");
            _commands.add("0:00:00");
            _commands.add("-r");
            _commands.add("50");
            _commands.add(_outPath);
        }


        String[] commands = new String[_commands.size()];
        String _pr = "";
        for (int i = 0; i < _commands.size(); i++) {
            commands[i] = _commands.get(i);
            _pr += commands[i];
        }
        Log.d("LOGCAT", "ffmpeg command:" + _pr + "-" + commands.length);
        return commands;

    }

????簡(jiǎn)略的說(shuō)下各種參數(shù) -f是他規(guī)定的圖片格式,-framerate就是幀率啦阅茶,fps就是一個(gè)int值蛛枚,一般5到25都行谅海,太少會(huì)影響視頻的流暢脸哀,太多會(huì)導(dǎo)致視頻播放過(guò)快,當(dāng)然這個(gè)fps一定要和當(dāng)時(shí)分割成圖片的fps是一模一樣的扭吁,當(dāng)時(shí)分割的如果太細(xì)撞蜂,會(huì)導(dǎo)致后來(lái)合成視頻的文件過(guò)大,因?yàn)榘凑找曈X(jué)殘留原理侥袜,15fps就會(huì)看做是連續(xù)的畫(huà)面了蝌诡,無(wú)停頓感。這里我默認(rèn)選擇5fps是因?yàn)?00毫秒取一幀省時(shí)間,幀數(shù)少枫吧,一會(huì)轉(zhuǎn)化視頻耗時(shí)時(shí)間少啊浦旱。-i表示輸入的媒體文件,一般是avi或mp4的視頻.-b是碼率,這個(gè)可以設(shè)置小一點(diǎn)九杂,就是1秒的媒體所占的大小限制颁湖,-ss是開(kāi)始的時(shí)間,-r是輸出的幀率控制例隆,這里是硬控制甥捺,這里我設(shè)置個(gè)大于framerate的數(shù)就行了,拼好命令以后镀层,就可以傳給ffmpeg進(jìn)行合成了镰禾。合成過(guò)程比較慢,因?yàn)橐簧婕暗揭曨l處理一般都會(huì)慢,靜靜等待執(zhí)行完之后就行了唱逢,到對(duì)應(yīng)目錄上查看合成之后的文件吴侦。
效果圖如下:


fzk.gif

這個(gè)demo的不足以及以后將會(huì)改進(jìn)的地方:

  1. 視頻分割成圖片使用的是系統(tǒng)的api,并沒(méi)有坞古,相當(dāng)于重復(fù)調(diào)用android native的接口备韧,反復(fù)的創(chuàng)建,銷(xiāo)毀資源绸贡,耗時(shí)比較多盯蝴。過(guò)一陣將會(huì)改成使用ffmpeg來(lái)進(jìn)行幀分解,我已經(jīng)跑過(guò)單獨(dú)的測(cè)試demo,效率是目前的10倍 - -听怕。
  2. 以后會(huì)增加彩色ascii碼的功能捧挺,現(xiàn)在是黑白的ascii碼,其實(shí)在圖片成ascii碼圖片之后尿瞭,再增加一步就行了闽烙,和原先的圖片進(jìn)行相交處理,如果是黑色的,就取原先圖片的彩色rgb黑竞,如果是白色的捕发,就不做處理。
    目前支持視頻avi很魂,mp4等常見(jiàn)格式轉(zhuǎn)化成avi扎酷,mp4,gif遏匆。后續(xù)會(huì)支持gif轉(zhuǎn)ascii 的gif或視頻法挨。

項(xiàng)目地址:https://github.com/LineCutFeng/PlayPicdio
歡迎star,你的收藏是我更新的動(dòng)力

系列文章:
Android平臺(tái)下的圖片/視頻轉(zhuǎn)Ascii碼圖片/視頻 (一)
Android平臺(tái)下的圖片/視頻轉(zhuǎn)Ascii碼圖片/視頻 (二)

參考文章:
在Android中使用FFmpeg(android studio環(huán)境)
極樂(lè)凈土----Android實(shí)現(xiàn)圖片轉(zhuǎn)ascii碼字符圖的一些嘗試
android_圖片轉(zhuǎn)視頻_image2video

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末幅聘,一起剝皮案震驚了整個(gè)濱河市凡纳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌帝蒿,老刑警劉巖荐糜,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異葛超,居然都是意外死亡暴氏,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)巩掺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)偏序,“玉大人,你說(shuō)我怎么就攤上這事胖替⊙腥澹” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵独令,是天一觀的道長(zhǎng)端朵。 經(jīng)常有香客問(wèn)我键耕,道長(zhǎng)娜搂,這世上最難降的妖魔是什么鹊奖? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任停忿,我火速辦了婚禮,結(jié)果婚禮上贤惯,老公的妹妹穿的比我還像新娘老速。我一直安慰自己啊研,他們只是感情好裙戏,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布乘凸。 她就那樣靜靜地躺著,像睡著了一般累榜。 火紅的嫁衣襯著肌膚如雪营勤。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音葛作,去河邊找鬼寿羞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛赂蠢,可吹牛的內(nèi)容都是我干的绪穆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼客年,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼霞幅!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起量瓜,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎途乃,沒(méi)想到半個(gè)月后绍傲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡耍共,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年烫饼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片试读。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杠纵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钩骇,到底是詐尸還是另有隱情比藻,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布倘屹,位于F島的核電站银亲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纽匙。R本人自食惡果不足惜务蝠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烛缔。 院中可真熱鬧馏段,春花似錦、人聲如沸践瓷。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)当窗。三九已至够坐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背元咙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工梯影, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人庶香。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓甲棍,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親赶掖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子感猛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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

  • 用兩張圖告訴你,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料奢赂? 從這篇文章中你...
    hw1212閱讀 12,699評(píng)論 2 59
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,737評(píng)論 25 707
  • 建筑學(xué)陪白,從廣義上來(lái)說(shuō),是研究建筑及其環(huán)境的學(xué)科膳灶。建筑學(xué)是一門(mén)橫跨工程技術(shù)和人文藝術(shù)的學(xué)科咱士。 建筑學(xué)所涉及的建筑藝術(shù)...
    楊屹耶閱讀 1,530評(píng)論 0 3
  • 比你優(yōu)秀的人毕箍,哪哪都比你優(yōu)秀弛房!這句話是在一個(gè)高手如云的課堂上,一個(gè)很厲害的牛人說(shuō)出來(lái)而柑,當(dāng)時(shí)聽(tīng)到這句話的時(shí)候文捶,我真的...
    大白老師啊閱讀 1,039評(píng)論 0 1
  • 1.偽元素-Element::after概念:在元素的內(nèi)容后面插入新內(nèi)容.說(shuō)明:常和“content”配合使用,多...
    才懂閱讀 96評(píng)論 0 0