bmp:以高质量保存 用于计算机
jpg:以良好的质量保存 用于计算机或者网络
png:以高质量保存
图片大小的计算公式:图片的总像素*每个像素的大小 (多出的一点是图片的信息)
单色:每个像素最多可以表示2种颜色 要么是黑要么是白 那么只需要使用长度为1的二进制位来表示 那么一个像素占1/8byte
16色:每个像素最多可以表示16种颜色 0000-1111 那么只需要使用长度为4的二进制位来表示 那么一个像素占1/2byte
256色:每个像素最多可以表示256种颜色 0000 0000-1111 1111 那么只需要使用长度为8的二进制位来表示 那么一个像素占1byte
24位:每个像素最多可以表示1600万多种颜色 0000 0000 0000 0000 0000 0000-1111 1111 1111 1111 1111 1111 那么一个像素占3byte rgb:r----1byte g----1byte b----1byte
Android中采用的是png格式 Android中采用ARGB Android中一个像素占4byte
2缩放加载大图片
[1]获取图片的分辨率
[2]获取手机的分辨率
[3]计算缩放比 用图片的分辨率宽高除以手机分辨率,最后在宽高中选大的
[4]按照大的去缩放
实现步骤:
[1]获取手机分辨率
// [1]获取手机的分辨率windowmanagerWindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);// 获取高int height = wm.getDefaultDisplay().getHeight();int width = wm.getDefaultDisplay().getWidth();System.out.println("width:" + width + " height:" + height);
[2]获取图片的分辨率
//创建一个位图工厂的配置参数BitmapFactory.Options options = new Options();//解码器不去真正的解析位图 但是还能够获取图片的宽和高信息options.inJustDecodeBounds = true;BitmapFactory.decodeFile("/mnt/sdcard/lings.jpg", options);//[2]获取图片的宽和高信息int imgWidth = options.outWidth;int imgHeight = options.outHeight;
[3]计算缩放比
//[3]计算缩放比int scale = 1;int scaleX = imgWidth/width;int scaleY = imgHeight/height;if(scaleX>=scaleY && scaleX > 1){scale = scaleX;}if(scaleX<scaleY && scaleY > 1){scale = scaleY;}
[4]按照缩放比进行显示
//[4]按照缩放比进行显示options.inSampleSize = scale;//[5]按照缩放比 进行解析位图options.inJustDecodeBounds = false;Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/lings.jpg", options);//[6]把bitmap显示iv上iv.setImageBitmap(bitmap);
注意:[1]真实手机是改不了 dvm分配的内存大小
[2]缩放加载大图片 就是加载分辨率特别大的图片
3创建原图的副本
package com.phone.fuben;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.widget.ImageView;public class MainActivity extends ActionBarActivity {private ImageView iv_src;private ImageView iv_copy;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 显示原图iv_src = (ImageView) findViewById(R.id.iv_src);// 显示副本iv_copy = (ImageView) findViewById(R.id.iv_copy);// [1]先把lings.jpg图片转换成bitmap显示到iv_srcBitmap srcBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.lings);// 操作图片// srcBitmap.setPixel(20, 30, Color.RED);iv_src.setImageBitmap(srcBitmap);// [2]创建原图的副本(模板代码)// 创建一个模板 相当于创建了一个大小和原图一样的空白的白纸Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(), srcBitmap.getConfig());// 想作画需要一个画笔Paint paint = new Paint();// 创建一个画布 把白纸铺到画布上Canvas canvas = new Canvas(copyBitmap);// 开始作画canvas.drawBitmap(srcBitmap, new Matrix(), paint);// 操作画出来的小猫图片for (int i = 0; i < 20; i++) {copyBitmap.setPixel(20 + i, 30, Color.RED);}// [3]把copybitmap显示到iv_copy上iv_copy.setImageBitmap(copyBitmap);}}
4图形处理的api
旋转
缩放
平移
镜面
倒影
package com.phone.fuben1;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.widget.ImageView;import com.phone.fuben1.R;public class MainActivity extends ActionBarActivity {private ImageView iv_src;private ImageView iv_copy;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 显示原图iv_src = (ImageView) findViewById(R.id.iv_src);// 显示副本iv_copy = (ImageView) findViewById(R.id.iv_copy);// [1]先把lings.jpg图片转换成bitmap显示到iv_srcBitmap srcBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.lings);// 操作图片// srcBitmap.setPixel(20, 30, Color.RED);iv_src.setImageBitmap(srcBitmap);// [2]创建原图的副本(模板代码)// 创建一个模板 相当于创建了一个大小和原图一样的空白的白纸Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(), srcBitmap.getConfig());// 想作画需要一个画笔Paint paint = new Paint();// 创建一个画布 把白纸铺到画布上Canvas canvas = new Canvas(copyBitmap);// 开始作画Matrix matrix = new Matrix();// 对图片进行旋转matrix.setRotate(20, srcBitmap.getWidth() / 2,srcBitmap.getHeight() / 2);// 对图片进行缩放matrix.setScale(0.5f, 0.5f);// 对图片进行平移matrix.setTranslate(20, 0);//对图片进行镜面效果//如果两个方法一起用就要用post前缀,post是在上一次修改的基础上进行再次修改 set每次操作都是最新的 会覆盖上次的操作matrix.setScale(-1.0f, 1);matrix.postTranslate(srcBitmap.getWidth(), 0);//对图片进行倒影效果matrix.setScale(1, -1.0f);matrix.postTranslate(0, srcBitmap.getHeight());canvas.drawBitmap(srcBitmap, matrix, paint);// [3]把copybitmap显示到iv_copy上iv_copy.setImageBitmap(copyBitmap);}}
5画画板小案例
package com.phone.painting;import java.io.File;import java.io.FileOutputStream;import android.app.Activity;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.SystemClock;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.widget.ImageView;public class MainActivity extends Activity {private Bitmap srcBitmap;private ImageView iv;private Bitmap copyBitmap;private Canvas canvas;private Paint paint;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 用来显示我们画的内容iv = (ImageView) findViewById(R.id.iv);// [1]获取原图bgsrcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg);// [2]获取原图的副本 相当于一个空白的白纸copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(), srcBitmap.getConfig());paint = new Paint();canvas = new Canvas(copyBitmap);// 开始作画canvas.drawBitmap(srcBitmap, new Matrix(), paint);canvas.drawLine(20, 30, 50, 80, paint);iv.setImageBitmap(copyBitmap);// [3]给iv设置一个触摸控件iv.setOnTouchListener(new OnTouchListener() {private int startX;private int startY;@Overridepublic boolean onTouch(View v, MotionEvent event) {// 获取当前事件类型int action = event.getAction();switch (action) {case MotionEvent.ACTION_DOWN:// 按下System.out.println("摸view");startX = (int) event.getX();startY = (int) event.getY();break;case MotionEvent.ACTION_MOVE:// 移动System.out.println("移动");// 获取结束位置int stopX = (int) event.getX();int stopY = (int) event.getY();// 不停的划线canvas.drawLine(startX, startY, stopX, stopY, paint);// 再次显示到控件上iv.setImageBitmap(copyBitmap);startX = stopX;startY = stopY;break;case MotionEvent.ACTION_UP:// 抬起System.out.println("抬起");break;}// true 监听器处理完事件了return true;}});}//点击按钮改变画笔 的颜色public void click1(View v) {paint.setColor(Color.RED);}//点击按钮加粗画笔public void click2(View v) {paint.setStrokeWidth(15);}//点击按钮保存图片public void click3(View v) {try {/*** format 保存图片的格式* quality 保存图片的质量* stream*///SystemClock.uptimeMillis() 当前手机开机时间File file = new File(Environment.getExternalStorageDirectory().getPath(),SystemClock.uptimeMillis()+".png");FileOutputStream fos;fos = new FileOutputStream(file);copyBitmap.compress(CompressFormat.PNG, 100, fos);//发送一条广播 欺骗系统图库的应用Intent intent = new Intent();//设置actionintent.setAction(Intent.ACTION_MEDIA_MOUNTED);intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));//发送一下广播sendBroadcast(intent);} catch (Exception e) {e.printStackTrace();}}}
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
6撕衣服小案例
原理:2张图片
package com.phone.syf;import android.R.integer;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.widget.ImageView;public class MainActivity extends ActionBarActivity {private Bitmap alterBitmap;private ImageView iv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);iv = (ImageView) findViewById(R.id.iv);// [1]获取要操作图片的原图Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.lings1);alterBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(), srcBitmap.getConfig());// 创建画笔Paint paint = new Paint();// 创建画布Canvas canvas = new Canvas(alterBitmap);// 开始作画canvas.drawBitmap(srcBitmap, new Matrix(), paint);iv.setImageBitmap(alterBitmap);// [3]给iv设置一个触摸事件iv.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// [4]具体判断一下触摸事件switch (event.getAction()) {case MotionEvent.ACTION_MOVE:// 移动事件for (int x = -7; x < 7; x++) {for (int y = -7; y < 7; y++) {if (Math.sqrt(x * x + y * y) < 7) {try {alterBitmap.setPixel((int) event.getX() + x,(int) event.getY() + y,Color.TRANSPARENT);} catch (Exception e) {}}}}// 更新一下iviv.setImageBitmap(alterBitmap);break;}return true;}});}}
7使用mediaplayer播放音频文件
[1]这个类用于播放音频或者视频
package com.phone.videoplayer;import android.app.Activity;import android.media.MediaPlayer;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}//点击按钮 播放一个音频文件public void click(View v){//[1]初始化mediaplayerMediaPlayer mediaPlayer = new MediaPlayer();//[2]设置要播放的资源位置 path 可以是网络 路径 也可是本地路径try {mediaPlayer.setDataSource("/mnt/sdcard/me.mp3");//[3]准备播放mediaPlayer.prepare();//[4]开始播放mediaPlayer.start();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
8百度音乐盒完善
package com.phone.baidumusic;import java.util.Timer;import java.util.TimerTask;import android.app.Service;import android.content.Intent;import android.media.MediaPlayer;import android.media.MediaPlayer.OnCompletionListener;import android.os.Binder;import android.os.Bundle;import android.os.IBinder;import android.os.Message;public class MusicService extends Service {private MediaPlayer mediaPlayer;@Overridepublic IBinder onBind(Intent intent) {return new MyBinder();}@Overridepublic void onCreate() {// [1]初始化mediaplayermediaPlayer = new MediaPlayer();super.onCreate();}@Overridepublic void onDestroy() {super.onDestroy();}//实现指定播放的位置public void seekTo(int position){mediaPlayer.seekTo(position);}// 播放音乐public void playMusic() {// [2]设置要播放的资源位置 path 可以是网络 路径 也可以是本地路径try {mediaPlayer.reset();mediaPlayer.setDataSource("/mnt/sdcard/me.mp3");// [3]准备播放mediaPlayer.prepare();// [4]开始播放mediaPlayer.start();// [5]更新进度条UpdateSeekBar();} catch (Exception e) {e.printStackTrace();}System.out.println("音乐播放了");}// 更新进度条的方法private void UpdateSeekBar() {//[1]获取到当前播放的总长度final int duration = mediaPlayer.getDuration();//[2]使用Timer定时器去定时获取当前进度final Timer timer = new Timer();final TimerTask task = new TimerTask() {@Overridepublic void run() {//[1]一秒钟获取一次当前进度int currentPosition = mediaPlayer.getCurrentPosition();//[4]拿着我们在mainactivity创建的handler 发消息 消息就可以携带数据Message msg =Message.obtain();Bundle data = new Bundle();data.putInt("duration", duration);data.putInt("currentPosition", currentPosition);msg.setData(data);//发送一条消息 mainactivity里面的handlermessage方法就会执行MainActivity.handler.sendMessage(msg);}};//100毫秒后每隔1秒执行一次run方法timer.schedule(task, 100, 1000);//当歌曲执行完毕后 把timer和timertask取消mediaPlayer.setOnCompletionListener(new OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {System.out.println("歌曲播放完成了");//把timer和timertask取消timer.cancel();task.cancel();}});}// 暂停音乐public void pauseMusic() {mediaPlayer.pause();System.out.println("音乐暂停了");}// 继续播放音乐public void rePlayMusic() {mediaPlayer.start();System.out.println("音乐继续播放了");}// [1]在服务的内部定义一个中间对象(IBinder)private class MyBinder extends Binder implements IService {@Overridepublic void callPlayMusic() {playMusic();}@Overridepublic void callPauseMusic() {pauseMusic();}@Overridepublic void callRePlayMusic() {rePlayMusic();}@Overridepublic void callSeekTo(int position) {seekTo(position);}}}
package com.phone.baidumusic;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.Handler;import android.os.IBinder;import android.view.View;import android.widget.SeekBar;import android.widget.SeekBar.OnSeekBarChangeListener;public class MainActivity extends Activity {//中间人对象private IService iService;private MyConn conn;private static SeekBar sbar;public static Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {//获取我们携带的数据Bundle data = msg.getData();int duration = data.getInt("duration");int currentPosition = data.getInt("currentPosition");//设置seekbar的进度sbar.setMax(duration);sbar.setProgress(currentPosition);};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//混合方式开启服务//[1]先调用startservice 目的是可以保证服务在后台长期运行Intent intent = new Intent(this, MusicService.class);startService(intent);//[2]调用bindservice 目的为了获取我们定义的中间人对象 就可以间接的调用服务里面的方法了conn = new MyConn();bindService(intent, conn, BIND_AUTO_CREATE);//[3]找到seekbar 设置进度sbar = (SeekBar) findViewById(R.id.seekBar1);//[4]给seekbar设置监听事件sbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {//当拖动停止的时候调用@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {iService.callSeekTo(seekBar.getProgress());}//当开始拖动@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}//当进度改变@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {}});}@Overrideprotected void onDestroy() {//当Activity销毁的时候 解绑服务unbindService(conn);super.onDestroy();}//点击按钮 播放音乐public void click1(View v){iService.callPlayMusic();}//点击按钮 暂停音乐public void click2(View v){iService.callPauseMusic();}//点击按钮 继续播放音乐public void click3(View v){iService.callRePlayMusic();}//监听服务的状态private class MyConn implements ServiceConnection{@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {iService = (IService) service;}@Overridepublic void onServiceDisconnected(ComponentName name) {}}}
package com.phone.baidumusic;public interface IService {public void callPlayMusic();public void callPauseMusic();public void callRePlayMusic();public void callSeekTo(int position);}
9mediaplayer的生命周期
同步和异步
同步:一般播放本地音乐
异步:播放网络音乐 不用开子线程
package com.phone.videoplayer;import android.app.Activity;import android.media.MediaPlayer;import android.media.MediaPlayer.OnPreparedListener;import android.os.Bundle;import android.view.View;import com.phone.videoplayeronline.R;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}//点击按钮 播放一个音频文件public void click(View v){//[1]初始化mediaplayerfinal MediaPlayer mediaPlayer = new MediaPlayer();//[2]设置要播放的资源位置 path 可以是网络 路径 也可是本地路径try {mediaPlayer.setDataSource("http://192.168.11.86:8080/xpg.mp3");//[3]准备播放mediaPlayer.prepareAsync();//设置一个准备完成的监听mediaPlayer.setOnPreparedListener(new OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {//开始播放mediaPlayer.start();}});} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
<uses-permission android:name="android.permission.INTERNET"/>
10surfaceview介绍
播放视频
mediaplayer 只能播放MP4格式或3gp格式
surfaceview 是一个重量级控件
内部维护了2个线程
A 加载数据 A负责显示
B 复制显示 b负责去加载数据
可以直接在子线程更新UI
11 VideoView控件介绍
VideoView 是对surfaceView 和 mediaplayer的封装
avi格式 或者rmvb格式
12 vitamio开源框架(有官网)
使用步骤:
[1]引入vitamio框架 引library
[2]在布局中定义VideoView
<io.vov.vitamio.widget.VideoView
android:id="@+id/vv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>[3]mainactivity代码
//使用vitamio//插件vitamio框架检查是否可用if(!LibsChecker.checkVitamioLibs(this)){return;}final VideoView vv = (VideoView)findViewById(R.id.vv);vv.setVideoPath("http://192.168.11.86:8080/aa.avi");vv.setOnPreparedListener(new OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {vv.start();}});//设置video的控制器vv.setMediaController(new MediaController(this));
[4]一定要在清单文件初始化InitActivity
<!-- 一定要在清单文件初始化InitActivity --><activity android:name="io.vov.vitamio.activity.InitActivity"></activity>
解码原理:使用的是一个开源项目 ffmpeg
13 照相机和录像机
package com.phone.camera;import java.io.File;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import android.support.v7.app.ActionBarActivity;import android.view.View;public class MainActivity extends ActionBarActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}//点击按钮进行照相public void click1(View v) {Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);File file = new File(Environment.getExternalStorageDirectory().getPath(),"ahha.png");//保存图片的位置intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));startActivityForResult(intent, 1);//发送一条广播 欺骗系统图库的应用Intent intent1 = new Intent();//设置actionintent.setAction(Intent.ACTION_MEDIA_MOUNTED);intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));//发送一下广播sendBroadcast(intent1);}//当开启的activity关闭的时候调用@Overrideprotected void onActivityResult(int arg0, int arg1, Intent arg2) {System.out.println("方法执行了");super.onActivityResult(arg0, arg1, arg2);}//点击按钮进行录像public void click2(View v) {Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);File file = new File(Environment.getExternalStorageDirectory().getPath(),"ahhaA.MP4");//保存图片的位置intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));startActivityForResult(intent, 2);//发送一条广播 欺骗系统图库的应用Intent intent1 = new Intent();//设置actionintent.setAction(Intent.ACTION_MEDIA_MOUNTED);intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));//发送一下广播sendBroadcast(intent1);}}
来自为知笔记(Wiz)