多媒体的概念:
文字、图片、音频、视频
图片
常见的图片格式:
png:无损保存图片,高质量的图片,.BMP格式保存的图像质量不变,文件也比较大,因为要保存每个像素的信息.
JPEG――是一种较常用的有损压缩图片,文件压缩变小,不保存每个像素的信息。
PNG--压缩不失真,它综合了JPG和GIF格式的优点
GIF―是一种图像交换格式,可提供压缩功能,但只支持256色,很少用于照片级图像处理工作.在PhotoShop中把对颜色数要求不高的图片变为索引色,再以GIF格式保存,使文件缩小后用更快的速度在网上传输.
单色位图:只能表示2种颜色 使用两个数字:0和1 使用一个长度为1的二进制数字就可以表示了 每个像素占用1/8个字节。
16色位图:能表示16种颜色 需要16个数字:0-15,0000 - 1111 使用一个长度为4的二进制数组就可以表示了 每个像素占用1/2个字节
256色位图:能表示256种颜色 需要256个数字:0 - 255,0000 0000 - 1111 1111 使用一个长度为8的二进制数字 每个像素占用1个字节
24位位图: 每个像素占用24位,也就是3个字节,所在叫24位位图 1600多万种
R:0-255,需要一个长度为8的二进制数字,占用1个字节
G:0-255,需要一个长度为8的二进制数字,占用1个字节
B:0-255,需要一个长度为8的二进制数字,占用1个字节
图片在计算机中的大小
图片的总大小 = 图片的总像素 * 每个像素占用的大小
加载大图片
计算机把图片所有像素信息全部解析出来,保存至内存
Android保存图片像素信息,是用ARGB保存 ,所以每个像素占用4个字节,很容易内存溢出。
在安卓程序中,加载大图片可以采用缩放的方式。
原理:第一步 :在解析图片的时候,我们使用位图工厂的api BitmapFactory.decodeFile(pathName, opts) ,在这个api中可以传入一个Options的对象,而我们解析图片时所需要的参数都封装进这个api中,把Options对象的inJustDecodeBounds的属性设为 true,通过文档可知,这样通过位图工场解析图图片,不会反悔位图,也不会为图像的像素申请内存。 =
第二步:通过Options对象拿到图片的宽高opt.outWidth;opt.outHeight; getWindowManager().getDefaultDisplay();拿到手机屏幕返回一个Display对象,通过display对象获得屏幕的宽高getWidth() getHeight();
第三步:拿图片的像素除以屏幕的像素,取大的值作为缩放比例,然后给options对象的inSampleSize属性设置缩放比例 再将opt.inJustDecodeBounds = false;这时候通过位图工厂解析图片,传入的options对象所需要解析的参数,就是我们需要的图片。
代码体现:
public void click(View v) {
//位图工场解析图片的参数封装在Options对象中
Options opts = new Options();
//不为像素申请内存,不返回位图对象
opts.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(),R.drawable.person,opts);
//拿到图片宽高
int imageHeight = opts.outHeight;
int imageWidth = opts.outWidth;
//拿到手机屏幕
Display dis = getWindowManager().getDefaultDisplay();
//获得手机屏幕的宽高
int screenHeight = dis.getHeight();
int screenWidth = dis.getWidth();
//计算缩放比例
int scale = 1;
int scaleHeight = imageHeight / screenHeight;
int scaleWidth = imageWidth / screenWidth;
if(scaleHeight >= scaleWidth && scaleHeight >= 1) {
scale = scaleHeight;
}else if(scaleWidth>=scaleHeight && scaleWidth>=1) {
scale = scaleWidth;
}
//设置缩放属性
opts.inSampleSize = scale;
opts.inJustDecodeBounds = false;
Bitmap bm = BitmapFactory.decodeResource(getResources(),R.drawable.person,opts);
ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setImageBitmap(bm);
}
在内存中创建图片的副本
由于我们直接加载的bitmap对象是只读的,我们无法对其做一些修改,要修改图片只能在内存中创建出一个一模一样的bitmap副本,然后修改副本
思路:第一步通过位图工厂拿到位图对象
第二步.在内存中创建一个与原图一模一样大小的bitmap对象,创建与原图大小一致的白纸Bitmap.createBitmap()
第三 步 创建画笔对象Paint
第四步 .创建画板对象,把白纸铺在画板上Canvas
第四步 开始作画,把原图的内容绘制在白纸上canvas.drawBitmap
代码 : 在两个imageView中通过创建图片副本,显示两个一样的图片
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bitmap bt = BitmapFactory.decodeResource(getResources(), R.drawable.person);
//创建一个与原图一样大小的白纸
Bitmap btCopy = Bitmap.createBitmap(bt.getWidth(), bt.getHeight(), bt.getConfig());
Paint pt = new Paint();
//创建画板对象,把白纸铺在画板上Canvas
Canvas cv = new Canvas(btCopy);
//4.开始作画,把原图的内容绘制在白纸上
cv.drawBitmap(bt, new Matrix(), pt);
ImageView iv_bitmap = (ImageView) findViewById(R.id.iv1);
ImageView iv_copyMap = (ImageView) findViewById(R.id.iv2);
iv_bitmap.setImageBitmap(bt);
iv_copyMap.setImageBitmap(btCopy);
}
}
通过图片副本完成画画板的案例
需求: 在activity上有一块画板 画板下方有四个Button 分别可以设置画笔的颜色为红色 绿色 设置画笔变粗 保存图片(保存的图片可以在安卓自带的图片应用中查看)
思路: 第一步 加载画画板的背景图
第二步 通过图片副本 创建一个与背景图一样的画板 显示在imageView上
第三步 由于我们在画板上作画。通过我们在屏幕上触摸移动,把我们触摸到的像素位置设置颜色。 所以我们需要给图片设置触摸侦听(setOnTouchListener)
在我们触摸屏幕时会触发onTouch方法,手指在屏幕上触摸有三种情况 分别为MotionEvent.ACTION_DOWN 手指摸到屏幕 MotionEvent.ACTION_MOVE手指在滑动 MotionEvent.ACTION_UP:
第四步 我们在手指摸到屏幕的时候记录位置,在手指移动的时候记录每次移动的位置,把每次移动的位置和手指触摸屏幕的位置之间划线drawLine 注意是每次绘制完毕之后,本次绘制的结束坐标变成下一次绘制的初始坐标,画完后将绘制后的图片设置到imageView
(监听事件内部类的返回值问题
true:告诉系统,这个触摸事件由我来处理
false:告诉系统,这个触摸事件我不处理,这时系统会把触摸事件传递给imageview的父节点
)
第五步 改变颜色 就是给画笔设置颜色
第六步 画笔加粗可以调用画笔setStrokeWidth(); 传入int 数值给画笔设置粗细
第七步 保存图片 调用bitmap的方法compress 可以保存图片
第八步 我们需要在保存图片的时候,就可以在系统的图片应用中看到图片 ,系统每次收到SD卡就绪广播时,都会去遍历sd卡的所有文件和文件夹,把遍历到的所有多媒体文件都在MediaStore数据库保存一个索引,这个索引包含多媒体文件的文件名、路径、大小。 图库每次打开时,并不会去遍历sd卡获取图片,而是通过内容提供者从MediaStore数据库中获取图片的信息,然后读取该图片,系统开机或者点击加载sd卡按钮时,系统会发送sd卡就绪广播,我们也可以手动发送就绪广播
代码:
public class MainActivity extends Activity {
private Canvas cancas;
private Paint paint;
private ImageView iv_drawBoard;
private Bitmap bt_copy;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//使用图片副本拿到可修改的副本图片
Bitmap bt = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
bt_copy = Bitmap.createBitmap(bt.getWidth(), bt.getHeight(), bt.getConfig());
paint = new Paint();
cancas = new Canvas(bt_copy);
cancas.drawBitmap(bt, new Matrix(), paint);
iv_drawBoard = (ImageView) findViewById(R.id.iv_drawBoard);
iv_drawBoard.setImageBitmap(bt_copy);
//设置触摸监听
iv_drawBoard.setOnTouchListener(new OnTouchListener() {
private int startX;
private int startY;
//完成滑动画笔功能
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN :
startX = (int) event.getX();
startY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE :
int X = (int) event.getX();
int Y = (int) event.getY();
cancas.drawLine(startX, startY, X, Y, paint);
startX = X;
startY = Y;
iv_drawBoard.setImageBitmap(bt_copy);
break;
case MotionEvent.ACTION_UP :
break;
}
return true;
}
});
}
//改变画笔颜色
public void click_red(View v) {
paint.setColor(Color.RED);
}
public void click_green(View v) {
paint.setColor(Color.GREEN);
}
//改变画笔粗细
public void click_rough(View v) {
paint.setStrokeWidth(7);
}
//将图片保存
public void click_save(View v) {
File file = new File(Environment.getExternalStorageDirectory(), "dazuo.PNG");
FileOutputStream stream = null;
try {
stream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//位图对象的compress方法可以保存图片
bt_copy.compress(CompressFormat.PNG, 100, stream);
//如果需要在图片应用看到图片,需要在保存图片之后发送广播,告知系统去遍历sd卡,把图片添加到MediaStore数据库
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
}
}
安卓开发者,产品爱好者
个人微博
原文:http://www.cnblogs.com/jiaowoxiaochen/p/4954388.html