1、大图片的加载:
图片在计算机中的大小
* 图片的总大小 = 图片的总像素 * 每个像素占用的大小
* 单色位图:只能表示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位位图
* R:0-255,需要一个长度为8的二进制数字,占用1个字节
* G:0-255,需要一个长度为8的二进制数字,占用1个字节
* B:0-255,需要一个长度为8的二进制数字,占用1个字节
加载大图片
- 计算机把图片所有像素信息全部解析出来,保存至内存
- Android保存图片像素信息,是用ARGB保存 a 透明度
- 手机屏幕320*480,总像素:153600
- 图片宽高2400*3200,总像素7680000
- 2400 / 320 = 7
- 3200 / 480 = 6
比例选择是7 比例选择是6的话图片宽度还是会溢出屏幕宽度。
代码:
options 中保存着许多选项的。 解析图片时所需的参数都在options 对象之中。
public void click(View v) {
// 选项 解析图片时所需的参数都在options 对象之中。
Options opt = new Options();
// 只解析边界。
opt.inJustDecodeBounds = true;
BitmapFactory.decodeFile("sdcard/dog.jpg", opt);
int imageWidth = opt.outWidth;
int imageHeight = opt.outHeight;
Display dp = getWindowManager().getDefaultDisplay();
int ScreenWidth = dp.getWidth();
int ScreenHeight = dp.getHeight();
// 计算屏幕的缩放比例;
int scale = 1;
int scaleWidth = imageWidth / ScreenWidth;
int scaleHeight = imageHeight / ScreenHeight;
if (scaleWidth > scaleHeight && scaleWidth >= 1) { //判断比例哪个大,就用哪个。
scale = scaleWidth;
} else if (scaleHeight > scaleWidth && scaleHeight >= 1) {
scale = scaleHeight;
}
// 设置缩放比例:
opt.inSampleSize = scale;
opt.inJustDecodeBounds = false; //设置好比例之后,记得将只解析边界置为false.
Bitmap bm= BitmapFactory.decodeFile("sdcard/dog.jpg", opt); //用位图工厂解析图片此时图片就在bm中。
ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setImageBitmap(bm); //设置图片显示。
}
创建图片的副本:
也就是copy,
//这个Bitmap对象是只读的。
Bitmap bm= BitmapFactory.decodeFile(“sdcard/zhuzi.jpg”);
先创建一张白纸:也是跟这个图片的尺寸一样的;
2、创建画笔
3、创建画板,把白纸铺上去。
4、作画。。。
Bitmap bm= BitmapFactory.decodeFile("sdcard/zhuzi.jpg");
//得到一个位图对象和bm的尺寸一样, 相当于画图的白纸。
Bitmap bmcopy= Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig()); //用位图对象创建,一张跟原图一样尺寸的 白纸
//创建画笔;
Paint paint= new Paint();
//创建画板;
Canvas cavas =new Canvas(bmcopy);
cavas.drawBitmap(bm, new Matrix(), paint); //在画板上开始作画,做的model也就是原来的位图。
ImageView iv = (ImageView) findViewById(R.id.iv_org);
ImageView iv_copy =(ImageView) findViewById(R.id.iv_copy);
iv.setImageBitmap(bm);
iv_copy.setImageBitmap(bmcopy);
简单特效:
平移,缩放。
Matrix mt= new Matrix(); //矩阵。
//平移
// mt.setTranslate(20, 40); 平移。
//缩放 x,y是缩放比例。 1表示不变。
mt.setScale(0.5f, 0.5f); //这个缩放是以左上角为缩放点缩放的。
mt.setScale(0.5f,0.5f, bm.getWidth()/2,bm.getHeight()/2); //这个是以中心点为中心进行缩小的。
//设置旋转
mt.setRotate(45);
//围绕中心旋转45度角。
用的比较多的是镜面和倒影;
镜面:也就是图片的宽高不变,x轴方向加个负号就可以了。
mt.setRotate(45, bmcopy.getWidth()/2, bmcopy.getHeight()/2);
cavas.drawBitmap(bm, mt, paint);
注意的是:
对于有两种效果的,第一个用set第二种用post设置。
//镜面效果。
平移之后x移出平面位置所以平移回来就可以,y轴方向不变。
mt.setScale(-1, 1);
mt.postTranslate(bmcopy.getWidth(), 0);
倒影:
就是x方向保持不变,Y方向给个负数,
//倒影效果
mt.setScale(1, -1);
mt.postTranslate(0, bmcopy.getHeight());
触摸侦听:
ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setOnTouchListener(new OnTouchListener){ //设置触摸侦听。
@Override // 触摸时该方法调用。
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
switch (action) {
//用户手指触摸到屏幕
case MotionEvent.ACTION_DOWN:
System.out.println("用户手指触摸屏幕");
break;
//用户手指抬离屏幕
case MotionEvent.ACTION_UP:
System.out.println("手指离开屏幕");
break;
//用户手指正在滑动。
case MotionEvent.ACTION_MOVE:
System.out.println("手指在移动");
break;
}
//true:告诉系统这个事件由这个组件自己处理。
//false:告诉系统这个事件它自己处理,抛出去交给父类。
return true;
}
});
创建画板作画;
package com.zh.paintplate;
import android.app.Activity;
import android.app.Notification.Action;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class MainActivity extends Activity {
private Canvas canvas;
private int startx;
private int starty;
private Paint paint;
private Bitmap bmcopy;
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获得Bitmap对象通过资源id的形式。
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
bmcopy = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),bm.getConfig());
paint = new Paint();
canvas = new Canvas(bmcopy); // 创建画板,铺上白纸。白纸一定要加上不然的话界面不显示图片。
//绘制图片
canvas.drawBitmap(bm, new Matrix(), paint);
iv = (ImageView) findViewById(R.id.iv);
iv.setImageBitmap(bmcopy);
// 设置触摸监听。
iv.setOnTouchListener(new OnTouchListener() {
@Override // 触摸时该方法调用。
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
switch (action) {
//用户手指触摸到屏幕
case MotionEvent.ACTION_DOWN:
startx = (int) event.getX();
starty = (int) event.getY();
break;
//用户手指抬离屏幕
case MotionEvent.ACTION_UP:
System.out.println("手指离开屏幕");
break;
//用户手指正在滑动。
case MotionEvent.ACTION_MOVE:
int x = (int) event.getX();
int y = (int) event.getY();
canvas.drawLine(startx, starty, x, y, paint);
//每次画完线后的结束坐标作为下一次的开始坐标。
startx= x;
starty=y;
iv.setImageBitmap(bmcopy); //画完图片后需要显示将图片从新甚至下显示位图。
break;
}
// 这个触摸侦听事件由该组件自己处理。
return true;
}
});
}
}
设置画笔的颜色:
//设置画笔的颜色为绿色。
paint.setColor(Color.GREEN);
可以设置画笔的宽度:
stroke ;画笔、
paint.setStrokeWidth(8); //设置画笔的宽度为8px像素。
画好图片的保存:
保存到内存卡上需要permisson:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
public void save(View v){
//文件的保存。
File file =new File("sdcard/dazuo.jpg"); 存放文件的地址。
try {
fos = new FileOutputStream(file); //通过文件输出输出流传输。
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bmcopy.compress(CompressFormat.JPEG, 100, fos); //第一个是格式format 压缩format定义的
}
保存图片 发送一广播。sd卡以就绪。
* SD每次准备的时候,系统其实是遍历sd卡所有文件,系统会把所有的多媒体文件,都在MediaStore数据库中生成一个索引,数据库中保存了文件的文件名、路径、大小、长度和艺术家
* 图库、音乐、视频程序每次启动时,其实不会去遍历sd卡寻找多媒体文件,而是直接从MediaStore数据库中读取多媒体文件,通过库中的索引找到对应的多媒体文件后,把文件显示在界面
得到外部的存储文件方法:
Environment.getExternalStorageDirectory()
//发送sd卡就绪广播是为了图库能加载显示该图片。
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MEDIA_MOUNTED); //设置action 说明sd卡已准备就绪。
intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory())); //里面内置了一个file开头。 符合data中的scheme:file
sendBroadcast(intent);
使触摸经过的地方变成透明色的方法:
int x= (int) event.getX();
int y = (int) event.getY();
bmcopy.setPixel(x, y, Color.TRANSPARENT); //使触摸经过的地方颜色变成透明色。 设置副本图片的像素。
设置屏幕的触摸监听需要注意:
在组件的外面down然后move不会触发触摸监听的。
组件的上面down然后超过组件范围仍然会触发触摸监听。
音乐: