概述
开门见山!先上效果图:
字符稍微密集了一点,不过放大来看大家应该能够看到确确实实是 字符画。
Android 端实现
Android开发中对图片的操作,显示一般都是通过Bitmap进行的,我们可以通过图片路径获取Bitmap对象:
static public Bitmap getBitmapByUri(Context context, Uri uri) {
Bitmap bit = null;
try {
bit = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri));
} catch (Exception ex) {
Log.i("utils", "" + ex.getMessage());
}
return bit;
}
一个图片的每一个像素其实都是一个值,这个值代表着这个像素的颜色,我们可以通过位运算来获取这个像素的ARGB值。
在安卓开发中要获取一个图片的每一个像素值其实很简单:
//按照参数范围获取像素数组
bitmap.getPixels(...);
//或者获取单个位置像素
bitmap.getPixel(x,y);
当我们获取到了像素值,转换成ARGB值后,我们获取带了RGB三个值,要如何判断什么颜色用什么字?要知道调色轮盘的颜色数不胜数:
这么多的颜色我们应该用什么样的标准给这么多颜色归类?
灰度值获取
灰度值是个很好的办法,什么是灰度值?
灰度值的范围只有0到255,计算方式一般是RGB三个值的平均值(也可以通过对RGB值进行加权计算不同的灰度),在很多图像处理里面的图片灰度化步骤用的就是这种方法。
原理跟思路清楚了,我们实现下把Bitmap转化成灰度值数组的方法:
static public int[][] getBitmap2GaryArray(Bitmap bitmap) {
int width = bitmap.getWidth(); //获取位图的宽
int height = bitmap.getHeight(); //获取位图的高
int[][] datas = new int[width][height]; //通过位图的大小创建像素点数组
//也可以使用getPixels方法来获取像素数组
//bitmap.getPixels(datas, 0, width, 0, 0, width, height);
int alpha = 0xFF < bitmap.getPixels();
for (int i = 0; i for (int j = 0; j int grey = bitmap.getPixel(i, j);
int red = (grey & 0x00ff0000) >> 16; //取高两位
int green = (grey & 0x0000ff00) >> 8; //取中两位
int blue = grey & 0x000000ff; //取低两位
grey = (int) ((float) red * 0.4 + (float) green * 0.3 + (float) blue * 0.3);
datas[i][j] = grey;
}
}
return datas;
}
在获取像素前我们还需要多做一步,为了防止图片过大(类似2K图/4K图),我们需要在获取像素前做一次统一标准化的压缩,我设置为宽为200,高等比例压缩。
...
//宽为200时,计算压缩比例是多少
float xScale = (float) 200 / bitmap.getWidth();
bitmap = BitmapUtils.compressBitmap(bitmap, xScale, xScale);
...
static public Bitmap compressBitmap(Bitmap bitmap, float sx, float sy) {
Matrix matrix = new Matrix();
matrix.setScale(sx, sy);
Log.i("utils_compressBitmap", "" + sx + "," + sy);
Bitmap bit = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
Log.i("utils_compressBitmap", "" + bit.getWidth() + "," + bit.getHeight());
//记得把不用的bitmap进行回收,以防止OOM
bitmap.recycle();
return bit;
}
当我们通过压缩好的图片获取到了它的灰度值数组,现在我们就可以根据灰度值转换为对应的文字了,我给了灰度值15个等级,根据颜色的深度给对应的中文字:(0是黑色,255是白色)
static String[] arr = {"餮", "淼", "圆", "困", "品", "回", "田", "凸", "口", "王", "天", "干", "工", "十", "一"};
我们制定好字符等级,那么要怎么根据数组制作图片呢?
根据 字符 绘制 Bitmap
上面说过图片的操作在Android中一般都在Bitmap进行的,所以我们要想绘制一张新的图片,那么就创建一个新的Bitmap对象,绘制的事情交给万能的画布就好了,画布带有文字绘制接口完美的符合我们需求:
static public Bitmap array2Bitmap(int[][] garyDatas, int width, int height) {
//绘制一个字对应一个像素,所以新绘制的Bitmap的大小应该乘上字体大小
Bitmap whiteBgBitmap = Bitmap.createBitmap(width * 6 + 20, height * 6 + 20, Bitmap.Config.ARGB_8888);
//在Bitmap上创建画布
Canvas canvas = new Canvas(whiteBgBitmap);
//绘制白色背景
canvas.drawARGB(255, 255, 255, 255);
//初始化画笔
Paint mPaint = new Paint();
mPaint.setStrokeWidth(1);
mPaint.setColor(Color.BLACK);
mPaint.setTextSize(6);
int x = 0;
//遍历灰度值数组
for (int xIndex = 10; x int y = 0;
for (int yIndex = 10; y //获取灰度值对应的字符
int charIndex = garyDatas[x][y] / 18;
String _char = arr[charIndex];
//在对应的坐标绘制字符
canvas.drawText(_char, xIndex, yIndex, mPaint);
y++;
}
x++;
}
return whiteBgBitmap;
}
绘制完成后输出Bitmap,下一步是把Bitmap保存为本地图片,关键代码如下:
...
File photo = new File(Environment.getExternalStorageDirectory() + "/" + dirName, String.format("CharPic_%d.jpg",System.currentTimeMillis()));
File dir = new File(photo.getParent());
if(!dir.exists()){
dir.mkdirs();
}
photo.createNewFile();
saveBitmapToJPG(bmp, photo);
...
static private void saveBitmapToJPG(Bitmap bitmap, File photo) throws IOException {
OutputStream stream = new FileOutputStream(photo);
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream);
stream.close();
bitmap.recycle();
}
下一步我们为了在系统相册更好的找到我们的图片,我们可以把图片发送一个广播来通知系统相册:
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(photo);
mediaScanIntent.setData(contentUri);
context.sendBroadcast(mediaScanIntent);
以上就是图片转成字符画的全部代码与讲解。可能有的人会问这样的功能,除了酷炫,有趣,牛逼之外,做出来有什么用?我只能问得好!乍一看好像用处不大,但是基于这个功能我们可以做短视频转换字符画视频。
奉上完整的源码,觉得有趣的请star一下呗。
完整项目源码地址:
- https://github.com/452kinton/CharacterDance
作者:Kinton
来源:https://www.jianshu.com/p/16ef3bf9ac5c
技术交流,欢迎加我微信:ezglumes ,拉你入技术交流群。
推荐阅读:
音视频面试基础题
OpenGL ES 学习资源分享
一文读懂 YUV 的采样与格式
OpenGL 之 GPUImage 源码分析
推荐几个堪称教科书级别的 Android 音视频入门项目
觉得不错,点个在看呗~
最后
以上就是简单早晨为你收集整理的android studio bitmap转jpg_Android 实现 图片 转 字符画 效果的全部内容,希望文章能够帮你解决android studio bitmap转jpg_Android 实现 图片 转 字符画 效果所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复