作者:Solang

链接:

https://www.jianshu.com/p/357af674a735

本文由作者授权发布。

1 概述

抖音上炫代码的不少,有些真的让人叹为观止,作为一个androider,当我看到下面这段舞蹈的时候,终于忍不住了,想要通过android实现一样的效果。

这么好玩的东西,为啥就没有大佬做呢,原因可能有两个,一是真的难,二是出力不讨好,难以达到最终效果,一番尝试后,技术问题都解决了,但并没有达到电脑端美感,手机屏幕还是太小了。

这是电脑端的静态图

这是手机端的

还有一个普通的头像,做成ascii图后,简直美到窒息

下面开始分析代码,首先根据图片像素灰度转为ascii字符,这在网上有现成的java代码,android上只需要改一点api就可以,代码如下。

public static Bitmap createAsciiPic(final String path, Context context) {        final String base = "#8XOHLTI)i=+;:,.";// 字符串由复杂到简单//        final String base = "#,.0123456789:;@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";// 字符串由复杂到简单        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);    }

这样处理完得到的ascii文本,但我们需要的是ascii图片,那我们需要怎么做呢,截屏?

请读者思考10秒钟,想想自己的解决方案。

我这里通过TextPanit和StaticLayout实现的,也可以new一个TextView,写入文本,然后把Textview的缓冲区转换为图片,但是这种StaticLayout的方式更底层,更有效,代码如下:

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

        TextPaint textPaint = new TextPaint();        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,

                layout.getHeight() + 20, Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmap);        canvas.translate(10, 10);        canvas.drawColor(Color.WHITE);        layout.draw(canvas);

        Log.d("textAsBitmap",

                String.format("1:%d %d", layout.getWidth(), layout.getHeight()));

        return bitmap;

    }

相对于电脑端有无边无际的txt编辑框,android里text是有字数限制的,所以原始图片如果像素过多的话就要进行尺寸压缩。

而且textPaint的这个设置特别重要textPaint.setTypeface(Typeface.MONOSPACE);字体对效果的影响太大了,失之毫厘谬以千里,这是一个大坑,说多了都是时间。

我在项目里集成了一个图片选择库,可以直接把拍的照片转化为ascii图,碰到一个问题就是拍照图片拿到后都会自动旋转90度,很是困惑,虽然找到了处理方法,但系统为啥要作旋转处理,还请知道的大神告知原因。

处理代码如下:

public static String amendRotatePhoto(String originpath, Context context) {

    // 取得图片旋转角度    int angle = readPictureDegree(originpath);

    // 把原图压缩后得到Bitmap对象    if (angle != 0) {        Bitmap bmp = getCompressPhoto(originpath);        Bitmap bitmap = rotaingImageView(angle, bmp);        return savePhotoToSD(bitmap, context);    } else {        return originpath;    }}

用到的方法:

public static int readPictureDegree(String path) {    int degree = 0;    try {        ExifInterface exifInterface = new ExifInterface(path);        int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);        switch (orientation) {            case ExifInterface.ORIENTATION_ROTATE_90:                degree = 90;                break;            case ExifInterface.ORIENTATION_ROTATE_180:                degree = 180;                break;            case ExifInterface.ORIENTATION_ROTATE_270:                degree = 270;                break;        }    } catch (IOException e) {        e.printStackTrace();    }    return degree;}

public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {    Bitmap returnBm = null;    // 根据旋转角度,生成旋转矩阵    Matrix matrix = new Matrix();    matrix.postRotate(angle);    try {        // 将原始图片按照旋转矩阵进行旋转,并得到新的图片        returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);    } catch (OutOfMemoryError e) {    }    if (returnBm == null) {        returnBm = bitmap;    }    if (bitmap != returnBm) {        bitmap.recycle();    }    return returnBm;}

这些代码都在文末的项目里。

按说拿到ascii图后,想要把整个视频转换成ascii字符视频就很简单了。只要把视频逐帧抽成图片,图片转换后,再合成为视频播放出来,但我视频库用的不多,希望有能力的朋友可以帮助完成最后一步。

最后,也希望朋友们能把一些有趣的想法实践到android项目中来,让搬砖之余,有更多的乐趣。

github地址

https://github.com/meiniepan/Pic2Ascii


抖音上很火的字符画 Android 实现相关推荐

  1. android 字符画,抖音上很火的字符画 Android 实现 | 视频转换实现

    作者:Line_cut_feng 链接:https://www.jianshu.com/p/a14f1ac558e1 之前我推送过抖音上很火的字符画 Android 实现,当时文末:按说拿到ascii ...

  2. java抖音字符视频_抖音上很火的字符画 Android 实现 | 视频转换实现

    最后像国际象棋格子一样,一块一块的替换掉,由于计算相对比较复杂,所以耗时比较长,因此当时那个demo也让我搁置了. 最近看到这篇日推,不由得眼前一亮,因为很少有人在android端做这种东西,因为算法 ...

  3. 抖音上很火的动态相册(末尾附加下载地址)

    抖音上很火的动态相册(末尾附加下载地址) 一.相册简介 二.部分代码简介及其运用 三.修改指南 四.总结及其获取方式 一.相册简介 1.首先该相册是用大家熟悉的HTML.CSS在此基础之上调用了几个J ...

  4. 生日祝福卡片 html,抖音上很火的生日祝福语大全 过生日暖心写给女生祝福内容...

    愿你三冬暖,愿你春不寒.愿你天黑有灯,下雨有伞.愿你路上有良人伴,来看看抖音上很火的生日祝福语大全. 抖音上很火的生日祝福语大全 1.愿如梁上燕,岁岁常相见.生日快乐! 2.在你永远与春天接壤的梦幻里 ...

  5. python如何写生日快乐说说_抖音上很火的生日句子,适合过生日发的高逼格

    抖音上很火的生日时发的句子,还有给自己生日的高逼格祝福,码起来,迟早会用到. 抖音上很火的生日句子,适合过生日发的高逼格祝福: 1. 没有零点的生日祝福 没有煽情的语录 感恩所有 都是馈赠和成长 祝自 ...

  6. 抖音上很火的3D立体动态相册

    带背景音乐网站效果: http://www.fengzhao.icu/photos/html/%E6%8A%96%E9%9F%B3%E4%B8%8A%E5%BE%88%E7%81%AB%E7%9A%8 ...

  7. 抖音高贵气质的签名_抖音上很火的个性签名

    抖音的个性签名是一个让大家一眼就可以了解该账号的展示方式,同时在抖音里经常会有一些账号因为个性签名变火,这里我们就整理了一些在抖音上很火的个性签名,大家可以参考一下! 1.尊严这种东西,你得有实力扞卫 ...

  8. 抖音高贵气质的签名_抖音上很火的个性签名女生,抖音个性签名女有气质

    抖音上很火的个性签名女生,抖音个性签名女有气质 1.坠入爱河有什么意义?放弃一群男人,一个男人,我什至会想不到! 2.我还年轻,需要您的指导.我会谦虚地接受并纠正它,但是我永远不需要您的指导. 抖音上 ...

  9. 最近分享一款抖音上很火的七夕节程序员表白页面_html5七夕表白放烟花动画特效...

    html5七夕表白放烟花动画特效 最近分享一款抖音上很火的七夕节程序员表白页面.小姐姐,我好喜欢你,你愿意做我女朋友吗? 表白成功触发烟花背景动画特效. 表白内容:有人说,人的一生会遇到2920万人, ...

最新文章

  1. Python 中的 enumerate 函数
  2. JAVA8 获取叶节点_Java找出所有的根节点到叶子节点的节点值之和等于sum 的路径...
  3. mysql 大量列 动态变量_aardio动态mysql变量设置
  4. Samsung x210 Android makefile 的一些配置实例问题
  5. php strncmp,PHP中strncmp()函数比较两个字符串前2个字符是否相等的方法
  6. HDU 1286 找新朋友 (欧拉函数)
  7. HDU1256 画8【打印图案】
  8. C/C++代码虚拟化保护 在移动端的应用
  9. 5月25 python3.6—pymouse—pyhook_3安装问题
  10. abaqus2021安装及fortran关联
  11. 安卓手机超频CPU(无修饰CPU控制)
  12. 最全英语日期相关表达
  13. 根据经纬度获取地理位置
  14. 【Java并发编程 四】Java的进程与线程
  15. 软碟通(UltraISO)刻录光盘以及制作U盘启动盘教程
  16. python读word文档计算字数,Python 实现word count 简单计算源代码中的字符数、词数、行数。...
  17. 2020-27th-07 蒟蒻团 【陈睿的考验】详解
  18. JAVA Swing 中的表格
  19. Elasticsearch/Kibana 视频学习网址(亲测视频很好)
  20. Nokia 6300使用技巧收集+总结

热门文章

  1. Redis的发布订阅模式
  2. 计算机配置表中的内存是指什么,电脑里的性能选项中,处理器计划和内存使用所写的是什么意思...
  3. 【转】图片像素数、打印机分辨率、打印尺寸之间的关系
  4. 计算中值——如何快速找到一个数组的中值
  5. 手把手教你用JSP+Servlet+Tomcat实现一个最简单的Web应用
  6. 功能测试怎么做?2020常用功能测试方法【总结】
  7. Android 解决Smart Lock 打不开的问题
  8. Spring继续学习: IOC、Bean、拓展点.....
  9. android小助手,Gifty编辑小助手
  10. 06 SpringBoot企业实战多环境切换之Profile