多媒体编程
一、图片
【1】 图片的常见格式
bmp:以高质量保存,用于计算机
jpg:以良好的质量保存,用于计算机和网络
png:以高质量保存
android采用的是png格式,android采用ARGB,Android中的像素占4个byte
【2】 图片大小的计算公式:图片的总像素*每个像素的大小
bmp格式
单色:每个像素最多可以表示2种颜色,黑和白,
只需要使用长度为1的二进制位来表示,那么一个像素占1/8个byte
16色:每个像素最多可以表示16种颜色,0000 - 1111
只需要使用长度为4的二进制位来表示,那么一个像素占1/2个byte
256色:每个像素最多可以表示数256种颜色,0000 0000 - 1111 1111
只需要使用长度为8的二进制位,那么一个像素占1个byte
24位 :每个像素最多可以表示1600多万种颜色,那么一个像素占3个byte,相当于rgb
【3】 android中图片申请的内存与硬盘中的大小无关,与图片的像素和每个像素大小有关,android中每个像素的大小都是4byte
二、缩放加载大图
【1】 获取图片的分辨率
【2】 获取手机的分辨率
【3】 计算缩放比
【4】 计算出来的宽高,按照大的缩放
三、创建图片副本
【1】 创建一个与原图一样的bitmap,但是只是一个空白的
Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(),srcBitmap.getConfig())
【2】 创建画笔(Paint),创建画布(Canvas)
val paint= Paint()
val canvas = Canvas(copyBitmap)
【3】 画bitmap
canva.drawBitmap(bitmap,matrix,paint)
【4】 原图是无法修改的,副本才能修改
【5】 代码实现
// 原图
val srcBitmap = BitmapFactory.decodeResource(resources, R.drawable.ic_launcher)
iv_src.setImageBitmap(srcBitmap)
// 创建空白副本
val config: Bitmap.Config = srcBitmap.config ?: Bitmap.Config.ARGB_8888
val copyBitmap = Bitmap.createBitmap(srcBitmap.width, srcBitmap.height, config)
// 创建画布
val canvas = Canvas(copyBitmap)
canvas.drawBitmap(srcBitmap, Matrix(), Paint())
iv_copy.setImageBitmap(copyBitmap)
【6】 图形处理
1.旋转
val config: Bitmap.Config = srcBitmap.config ?: Bitmap.Config.ARGB_8888
val copyBitmap = Bitmap.createBitmap(srcBitmap.width, srcBitmap.height, config)
val canvas = Canvas(copyBitmap)
// 矩阵
val matrix = Matrix()
// 矩阵旋转
matrix.setRotate(50f, srcBitmap.width / 2f, srcBitmap.height / 2f)
canvas.drawBitmap(srcBitmap, matrix, Paint())
iv_copy.setImageBitmap(copyBitmap)
2.缩放
matrix.setScale(0.5f,0.5f)
3.平移
matrix.setTranslate(10f, 0f)
4.镜面
缩放和平移的组合
matrix.setScale(-1.0f, 1f)
// post是在上一次修改的基础上进行修改
matrix.postTranslate(srcBitmap.width.toFloat(), 0f)
5.倒影
matrix.setScale(1.0f, -1f)
// post是在上一次修改的基础上进行修改
matrix.postTranslate(0f, srcBitmap.height.toFloat())
四、画板
【1】 在原图的副本上面作画
【2】 创建副本
【3】 使用canvas画画
【4】 监听副本的触摸事件,画点
【5】 代码实现
private fun createDrawBitmap() {
val srcBitmap = BitmapFactory.decodeResource(resources, R.drawable.bg)
// 创建副本
copyBitmap = Bitmap.createBitmap(srcBitmap.width, srcBitmap.height, srcBitmap.config)
val canvas = Canvas(copyBitmap)
paint = Paint()
paint.color = Color.BLACK
val matrix = Matrix()
canvas.drawBitmap(srcBitmap, matrix, paint)
iv.setImageBitmap(copyBitmap)
var startX = 0f
var startY = 0f
iv.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
startX = event.x
startY = event.y
}
MotionEvent.ACTION_MOVE -> {
val endX = event.x
val endY = event.y
canvas.drawLine(startX, startY, endX, endY, paint)
iv.invalidate()
startX = endX
startY = endY
}
MotionEvent.ACTION_UP -> {
}
}
true
}
}
// 保存画出的bitmap
val file = File(
Environment.getExternalStorageDirectory().absolutePath,
"/png/${System.currentTimeMillis()}.png"
)
val fos = FileOutputStream(file)
copyBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)
// 发送扫描图库的广播
/*val intent = Intent()
intent.action = Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
intent.data =
Uri.fromFile(file)
sendBroadcast(intent)*/
// 只能扫描文件
MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath),
arrayOf("image/*"),null)
//注意:在android 4.4之前,扫描sd卡时,使用广播中的action=Intent.ACTION_MEDIA_MOUNTED
在4.4以后,不能使用这个action,因为没有权限,如果发送广播的话,可以使用Intent.ACTION_MEDIA_SCANNER_SCAN_FILE这个action
还有另一种方法,就是使用MediaScannerConnection.scanFile()这个方法
4.4后扫描的话,不能扫描目录,只能扫描文件