第九天

来源:互联网 发布:万网域名登录网址 编辑:程序博客网 时间:2024/04/29 05:27
1、计算机表示图形的几种方式
    BMP  以高质量保存,用于计算机
    JPG  以良好质量保存  用于计算机或网络
    png  以高质量保存
图片大小的计算公式
    图片的总像素*每个像素的大小
    单色: 每个像素最多可以表示两种颜色,要么是黑要么是白,只需要使用长度为1的二进制位来表示  那么一个像素占1/8个byte
    16色:  每个像素最大可以表示16中颜色,使用二进制表示000-111,只需要长度为4的二进制位表示,那么一个像素占1/2个byte
    256色:  每个像素最多可以表示256种颜色,使用二进制表示0000 0000 - 1111 1111 ,只需要使用长度为8的二进制位表示,那么一个像素占1个byte
    24位:  每个像素最多可以表示1600万多种颜色,   一个像素占3个byte
            r 占一个像素
            g  占一个像素
            b  占一个像素
    android种采用的png格式  android种采用ARGB  android种一个像素占4个byte
2、缩放加载加载大图片
    dalvak虚拟机加载图片与图片的实际大小无关,与图片的总像素*每个像素的大小有关
    【1】 获取手机的分辨率
    【2】 获取图片分辨率
    【3】 计算缩放比  图片宽/手机的宽   图片的高/手机的高
    【4】  如果不进行图形的缩放设置,那么会报oom异常(out of memory error)
  1. //[1] 获取屏幕分辨率
  2. WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
  3. int width = manager.getDefaultDisplay().getWidth();
  4. int height = manager.getDefaultDisplay().getHeight();
  5. Log.d("screenscale",width+"------"+height);
  6. //[2] 获取图片分辨率
  7. BitmapFactory.Options options = new BitmapFactory.Options();
  8. options.inJustDecodeBounds = true;
  9. Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/dog.jpg",options);
  10. int imgHeight = options.outHeight;
  11. int imgWidth = options.outWidth;
  12. Log.d("pictureInfo",imgWidth+"-----"+imgHeight);
  13. //[3] 计算缩放比
  14. int scale = 1;
  15. int scaleX = imgWidth / width;
  16. int scaleY = imgHeight / height;
  17. if(scaleX >= scaleY && scaleX > scale)
  18. scale = scaleX;
  19. else if(scaleY > scaleX && scaleY > scale)
  20. scale = scaleY;
  21. Log.d("scale",scale+"");
  22. //[4] 按照缩放比进行设置图片显示
  23. options.inSampleSize = scale;
  24. options.inJustDecodeBounds = false;
  25. Bitmap bitmap1 = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/dog.jpg",options);
  26. //[5] 设置图片显示
  27. iv.setImageBitmap(bitmap1);

3、创建原图的副本
  1. //[2] 开始准备作画
  2. //[2.1] 创建一个新的bitmap和原图配置一样
  3. Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
  4. //[2.2] 准备画笔
  5. Paint paint = new Paint();
  6. //[2.3] 准备一个画布,使用copyBitmap来进行相关的配置
  7. Canvas canvas = new Canvas(copyBitmap);
  8. //[2.4] 开始作画
  9. canvas.drawBitmap(srcBitmap,new Matrix(),paint);
  10. for(int x = 0;x < copyBitmap.getWidth();x++){ //添加一条黑线
  11. copyBitmap.setPixel(x,100,Color.BLACK);
  12. }
  13. //[3] 将画展示到控件上
  14. iv_copy.setImageBitmap(copyBitmap);

4、图形处理的api
    旋转: rotate
    缩放: scale
    平移: translate
    镜面: scale和translate的组合
    倒影: scale和translate的组合
  1. //[2.4] 图形旋转
  2. //matrix.setRotate(30,5f,6f);
  3. //[2.5] 图形缩放 前面的两个参数代表缩放的比例 后面的代表缩放的参考点
  4. //matrix.setScale(0.5f,0.5f,srcBitmap.getWidth()/2,srcBitmap.getHeight()/2);
  5. //[2.6] 图形平移
  6. //matrix.setTranslate(30f,30f);
  7. //[2.7] 图形的镜面效果
  8. //matrix.setScale(-1.0f,1);
  9. //matrix.postTranslate(srcBitmap.getWidth(),0);
  10. //[2.8] 图形的倒影效果
  11. //matrix.setScale(1.0f,-1.0f);
  12. //matrix.postTranslate(0,srcBitmap.getHeight());


5、画画板小案例
  1. package com.drawboard;
  2. import android.content.Intent;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.graphics.Canvas;
  6. import android.graphics.Color;
  7. import android.graphics.Matrix;
  8. import android.graphics.Paint;
  9. import android.net.Uri;
  10. import android.os.Bundle;
  11. import android.os.Environment;
  12. import android.os.SystemClock;
  13. import android.support.v7.app.AppCompatActivity;
  14. import android.view.MotionEvent;
  15. import android.view.View;
  16. import android.widget.ImageView;
  17. import android.widget.Toast;
  18. import java.io.File;
  19. import java.io.FileOutputStream;
  20. public class MainActivity extends AppCompatActivity {
  21. private ImageView iv;
  22. private Paint paint;
  23. private Bitmap copy;
  24. private Canvas canvas;
  25. private Bitmap src;
  26. @Override
  27. protected void onCreate(Bundle savedInstanceState) {
  28. super.onCreate(savedInstanceState);
  29. setContentView(R.layout.activity_main);
  30. iv = (ImageView) findViewById(R.id.iv);
  31. //[1] 获取原背景
  32. src = BitmapFactory.decodeResource(getResources(), R.drawable.background);
  33. //[2] 进行背景模型
  34. copy = Bitmap.createBitmap(src.getWidth(), src.getHeight(), src.getConfig());
  35. //[3] 获取画笔
  36. paint = new Paint();
  37. //[4] 获取画布,铺上背景
  38. canvas = new Canvas(copy);
  39. //[5] 在画布上作画
  40. canvas.drawBitmap(src, new Matrix(), paint);
  41. //[6] 显示在控件上
  42. iv.setImageBitmap(copy);
  43. //[7] 设置iv的监听事件
  44. iv.setOnTouchListener(new View.OnTouchListener() {
  45. private float startX;
  46. private float startY;
  47. private float stopX;
  48. private float stopY;
  49. @Override
  50. public boolean onTouch(View view, MotionEvent motionEvent) {
  51. //[1] 获取事件类型
  52. int action = motionEvent.getAction();
  53. switch (action) {
  54. case MotionEvent.ACTION_DOWN: //当按下的时候触发
  55. //[1] 获取触摸的坐标
  56. startX = motionEvent.getX();
  57. startY = motionEvent.getY();
  58. break;
  59. case MotionEvent.ACTION_MOVE: //当手指移动的时候触发
  60. //[2] 获取移动中的坐标
  61. stopX = motionEvent.getX();
  62. stopY = motionEvent.getY();
  63. //[3] 画线,从开始到结束
  64. canvas.drawLine(startX,startY,stopX,stopY,paint);
  65. //[3.1] 更新图片
  66. iv.setImageBitmap(copy);
  67. //[4] 更新原点
  68. startX = stopX;
  69. startY =stopY;
  70. break;
  71. case MotionEvent.ACTION_UP: //当手指松开的时候调用
  72. break;
  73. }
  74. return true;
  75. }
  76. });
  77. }
  78. //点击按钮更改颜色
  79. public void setColor(View view) {
  80. paint.setColor(Color.BLUE);
  81. }
  82. //点击按钮加粗画笔
  83. public void setStrokW(View view) {
  84. paint.setStrokeWidth(10.0f);
  85. }
  86. //点击按钮保存图片 并且发送广播通知图库更新图片显示
  87. public void save(View view) {
  88. try {
  89. boolean isSave = copy.compress(Bitmap.CompressFormat.PNG, 100, new FileOutputStream(new File(Environment.getExternalStorageDirectory().getPath(), SystemClock.uptimeMillis()+".png")));
  90. Intent intent = new Intent();
  91. intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
  92. intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
  93. sendBroadcast(intent); //4.4以后不能这么发广播,会报 Permission Denial: not allowed to send broadcast android.intent.action.MEDIA_MOUNTED
  94. if(isSave){
  95. Toast.makeText(getApplicationContext(),"保存成功",Toast.LENGTH_SHORT).show();
  96. }else{
  97. Toast.makeText(getApplicationContext(),"保存失败",Toast.LENGTH_SHORT).show();
  98. }
  99. } catch (Exception e) {
  100. e.printStackTrace();
  101. }
  102. }
  103. public void clear(View view){
  104. copy = Bitmap.createBitmap(copy.getWidth(), copy.getHeight(), copy.getConfig());
  105. canvas = new Canvas(copy);
  106. canvas.drawBitmap(src,new Matrix(),paint);
  107. iv.setImageBitmap(copy);
  108. }
  109. }


6、撕衣服小案例
    原理:两张图片
  1. package com.mosatsu;
  2. import android.graphics.Bitmap;
  3. import android.graphics.BitmapFactory;
  4. import android.graphics.Canvas;
  5. import android.graphics.Color;
  6. import android.graphics.Matrix;
  7. import android.graphics.Paint;
  8. import android.os.Bundle;
  9. import android.support.v7.app.AppCompatActivity;
  10. import android.view.MotionEvent;
  11. import android.view.View;
  12. import android.widget.ImageView;
  13. public class MainActivity extends AppCompatActivity {
  14. private ImageView iv;
  15. @Override
  16. protected void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.activity_main);
  19. iv = (ImageView)findViewById(R.id.iv);
  20. Bitmap src = BitmapFactory.decodeResource(getResources(), R.drawable.pre19);
  21. final Bitmap copy = Bitmap.createBitmap(src.getWidth(), src.getHeight(), src.getConfig());
  22. Paint paint = new Paint();
  23. final Canvas canvas = new Canvas(copy);
  24. Matrix matrix = new Matrix();
  25. canvas.drawBitmap(src,matrix,paint);
  26. iv.setImageBitmap(copy);
  27. //[1] 给iv设置触摸事件
  28. iv.setOnTouchListener(new View.OnTouchListener() {
  29. @Override
  30. public boolean onTouch(View view, MotionEvent motionEvent) {
  31. int action = motionEvent.getAction();
  32. switch (action) {
  33. case MotionEvent.ACTION_MOVE:
  34. float x = motionEvent.getX();
  35. float y = motionEvent.getY();
  36. for (int i = -20; i < 20; i++) {
  37. for(int j = -20;j < 20;j++){
  38. if(Math.sqrt(i*i+j*j) < 20){ //为了达到圆形的效果,使用了勾股定理
  39. try {
  40. copy.setPixel((int) motionEvent.getX() + i, (int) motionEvent.getY() + j, Color.TRANSPARENT); //设置为透明
  41. } catch (Exception e) {
  42. }
  43. }
  44. }
  45. }
  46. iv.setImageBitmap(copy);
  47. break;
  48. }
  49. return true;
  50. }
  51. });
  52. }
  53. }


7、使用mediaPlayer播放音频文件
    作用:用于播放音频和视频的
    在Activity中声明的MediaPlayer在Activity销毁的时候并不能被销毁
8、百度音乐盒完成
9、mediaplayer的生命周期
    prepare()同步:一般播放本地音乐
    prepareAsync()异步:一般播放网络音乐  不用开子线程
  1. //[1] 准备mediaplayer
  2. player = new MediaPlayer();
  3. //[2] 设置网络数据源
  4. player.setDataSource("http://192.168.171.195:8080/dhc.mp3");
  5. //[3] 进行异步准备,由底层C准备线程方法
  6. player.prepareAsync();
  7. //[4] 在准备完成后开始播放
  8. player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
  9. @Override
  10. public void onPrepared(MediaPlayer mediaPlayer) {
  11. player.start();
  12. }
  13. });


10、surfaceView介绍
    [1]  SurfaceView是一个重量级控件,需要一段时间进行加载,为了防止出现不能播放视频的情况,采用其回调方法
    [2]  MediaPlayer只能播放mp4或者3gp格式
    [3]  内部维护了两个线程,
            A  负责加载数据  ---->去显示数据
            B  负责显示  --->显示完加载的数据--->去加载数据
    [4]  可以直接在子线程中更新UI,进程相关的控件也可以直接更新UI
    [5]  MediaPlayer的可能出现的问题

问题1:

05-20 18:35:24.305: E/MediaPlayer(19765): stop called in state 4
05-20 18:35:24.305: E/MediaPlayer(19765): error (-38, 0)

原因:是在调用prepareAsync()则以异步方式进入Prepared状态过程中即preparing状态中,调用了stop方法。

参考:http://stackoverflow.com/questions/8796956/mediaplayer-stop-called-in-state-4

来源: http://blog.sina.com.cn/s/blog_5da93c8f0101qyd2.html

问题2:

Media Player called in state 0, error (-38,0)

原因是在You're using prepareAsync, which is asynchronous. That is, you should wait for the onPrepared callback before you do anything that relies on the preparation to be complete (like calling start). That's why you get the "start called in state 4" error message (state 4 is MEDIA_PLAYER_PREPARING).

即调用 prepareAsync,在preparing过程中调用了start。

参考:http://stackoverflow.com/questions/16495276/mediaplayer-track-change-issue 

问题3:

Attempt to call getDuration without a valid mediaplayer in media player on android

原因:在preparing过程中调用了getDuration方法。

You might be calling getDuration before the file is fully loaded.

参考:http://stackoverflow.com/questions/6026288/attempt-to-call-getduration-without-a-valid-mediaplayer-in-media-player-on-andr 

问题4:如果你使用VideoView播放过MP4视频,你可能碰到过类似下面的问题:

MediaPlayer error (1, -2147483648)如果你查阅文档,会发现1其实代表MEDIA_ERROR_UNKNOWN,不过文档对-2147483648(0x80000000)没有做什么说明,实际上它也是代表unknown error的意思。真正的原因在于,MP4有多种编码格式,例如H.264,H.263等,而android版本较低的机器只支持部分编码。一旦遭遇不被支持的编码格式,MediaPlayer可能就会抛出上面的错误信息。如果你也遇到这类问题,你可以使用一些视频软件查看视频的编码格式,然后转换为普遍支持的格式。

11、VideoView控件介绍
  1. vv = (VideoView)findViewById(R.id.vv);
  2. vv.setVideoPath("http://192.168.171.195:8080/cc.3gp");
  3. vv.start();
12、vitmaio   万能视频框架
    
0 0