Android12
2016-12-14 16:54
337 查看
Android12
计算机图形的表示方法
位图
一个一个像素点算法:
位图图形的大小=位图的宽度 * 位图的高度 * 每一个像素点占据字节数
位图的宽度 * 位图的高度 是分辨率
BMP的格式:
单色位图 1个bit byte = 1/8
16色位图 4个bit byte = 4/8
256色位图 8个bit byte = 8/8
24位位图 24个bit byte = 24/8
矢量图
根据比例加载图片到内存
public void loadImage(View view){ //加载一个图片到内存 显示到imageview的控件上. Bitmap bitmap = BitmapFactory.decodeFile("mnt/sdcard/big.jpg"); //32位的位图, argb iv.setImageBitmap(bitmap); } -------------------------------------- BitmapFactory.decodeStream(is);(最多用) BitmapFactory.decodeFile("mnt/sdcard/big.jpg");(次多用(getFiles(),getcache(),SDcard中范围)) BitmapFactory.decodeResource(res, id);(相对少)
Android下面的位图默认是32位
ARGB : alpha red green blue 每一个是8位
图片需要加载内存的大小(1.6M在硬盘) = 宽度 * 高度 * (32/8)(内存中15.4M)
加载大图片到内存
//加载一个图片到内存 显示到imageview的控件上. Options opts = new Options();//创建一个选项条件 opts.inSampleSize = 4;//设置采样率,宽高分别是原图的1/4,总像素个数就变成原图的1/16 Bitmap bitmap = BitmapFactory.decodeFile("mnt/sdcard/big.jpg", opts); //32位的位图, argb iv.setImageBitmap(bitmap);
//1.得到图片的宽高信息. ExifInterface exif = new ExifInterface("mnt/sdcard/big.jpg"); int width = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0); int height = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0); System.out.println("widtH:"+width); System.out.println("height:"+height); //2.获取屏幕的宽高 WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); int screenWidth = wm.getDefaultDisplay().getWidth(); int screenHeight = wm.getDefaultDisplay().getHeight(); System.out.println("屏幕width:"+screenWidth); System.out.println("屏幕height:"+screenHeight);
图片的缩放
public void processImage(View view){ //得到原始位图的对象 Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/tu1.jpg"); iv_src.setImageBitmap(srcBitmap); //缩放后 显示一个缩放后的图片 在iv_dest //用代码编辑图片,最好处理都是图片在内存中的拷贝,不去处理原图. Bitmap copyedBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig()); //临摹.创建一个画板 Canvas canvas = new Canvas(copyedBitmap); //创建画笔 Paint paint = new Paint(); paint.setColor(Color.BLACK); //作画 Matrix matrix = new Matrix();//按照1:1的比例作画 matrix.setScale(0.6f, 0.6f); canvas.drawBitmap(srcBitmap, matrix, paint); iv_dest.setImageBitmap(copyedBitmap); }
图片的平移旋转镜面和倒影效果
//平移 Bitmap copyedBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig()); //临摹.创建一个画板 Canvas canvas = new Canvas(copyedBitmap); //创建画笔 Paint paint = new Paint(); paint.setColor(Color.BLACK); //作画 Matrix matrix = new Matrix();//按照1:1的比例作画 matrix.setTranslate(100, 100); canvas.drawBitmap(srcBitmap, matrix, paint); iv_dest.setImageBitmap(copyedBitmap);
//旋转 Bitmap copyedBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig()); //临摹.创建一个画板 Canvas canvas = new Canvas(copyedBitmap); //创建画笔 Paint paint = new Paint(); paint.setColor(Color.BLACK); //作画 Matrix matrix = new Matrix();//按照1:1的比例作画 matrix.setRotate(180, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2); canvas.drawBitmap(srcBitmap, matrix, paint); iv_dest.setImageBitmap(copyedBitmap);
//镜面 Canvas canvas = new Canvas(copyedBitmap); //创建画笔 Paint paint = new Paint(); paint.setColor(Color.BLACK); //作画 Matrix matrix = new Matrix();//按照1:1的比例作画 matrix.setScale(-1, 1); matrix.postTranslate(srcBitmap.getWidth(), 0); canvas.drawBitmap(srcBitmap, matrix, paint); iv_dest.setImageBitmap(copyedBitmap);
//倒影 Bitmap copyedBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig()); //临摹.创建一个画板 Canvas canvas = new Canvas(copyedBitmap); //创建画笔 Paint paint = new Paint(); paint.setColor(Color.BLACK); //作画 Matrix matrix = new Matrix();//按照1:1的比例作画 matrix.setScale(1, -1); matrix.postTranslate(0, srcBitmap.getHeight()); canvas.drawBitmap(srcBitmap, matrix, paint); iv_dest.setImageBitmap(copyedBitmap);
随手涂鸦的ui
view水平方向线性布局拖动条SeekBar
ImageView
// 设置画笔的颜色 paint.setColor(Color.BLACK); // 设置画笔的宽度 paint.setStrokeWidth(5);
随手涂鸦的核心逻辑
触摸事件的操作:iv.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN:// 按下 case MotionEvent.ACTION_MOVE:// 移动 case MotionEvent.ACTION_UP:// 离开 return true; //false代表的是事件没有处理完毕,等待事件处理完毕, true代表事件已经处理完毕了. } }
System.out.println("摸到"); startX = (int) event.getX(); startY = (int) event.getY(); System.out.println("移动"); int newX = (int) event.getX(); int newY = (int) event.getY(); //画直线 canvas.drawLine(startX, startY, newX, newY, paint); iv.setImageBitmap(alterBitmap); // 记得重新初始化手指在屏幕上的坐标 startX = (int) event.getX(); startY = (int) event.getY();
随手涂鸦的细节
File file = new File(Environment.getExternalStorageDirectory(), SystemClock.currentThreadTimeMillis() + ".jpg"); FileOutputStream stream = new FileOutputStream(file); ------------------------------------------ //保存图片的API,格式,质量,输出流sdcard位置 alterBitmap.compress(CompressFormat.JPEG, 100, stream); //欺骗系统,插入SDcard的广播 Intent intent = new Intent(); intent.setAction(Intent.ACTION_MEDIA_MOUNTED); intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory())); sendBroadcast(intent); <!-- 写入SDcard的权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
撕衣服
public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: x = (int) event.getX(); y = (int) event.getY(); for(int i=-3;i<4;i++){ for(int j=-3;j<4;j++){ if(Math.sqrt(i*i+j*j)<=3){ try { alterBitmap.setPixel(x+i, y+j, Color.TRANSPARENT); } catch (Exception e) { e.printStackTrace(); } } } } iv_pre.setImageBitmap(alterBitmap); break; case MotionEvent.ACTION_MOVE: x = (int) event.getX(); y = (int) event.getY(); for(int i=-3;i<4;i++){ for(int j=-3;j<4;j++){ if(Math.sqrt(i*i+j*j)<=3){ try { alterBitmap.setPixel(x+i, y+j, Color.TRANSPARENT); } catch (Exception e) { e.printStackTrace(); } } } } iv_pre.setImageBitmap(alterBitmap); break; case MotionEvent.ACTION_UP: break; } return true;// 事件结束被消费掉了 } });
getX和getRawX区别
getX到控件的距离getRawX到屏幕的距离
图片的颜色处理
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sb_red = (SeekBar) findViewById(R.id.sb_red); iv = (ImageView) findViewById(R.id.iv); sb_red.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { int progress = seekBar.getProgress(); float result = progress/50.0f; System.out.println("变化的百分比为:"+result); ColorMatrix cm = new ColorMatrix(); cm.set(new float[] { 1*result, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 }); paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(srcBitmap, new Matrix(), paint); iv.setImageBitmap(copyedBitmap); } });
音乐播放器的状态图
mediaPlayer = new MediaPlayer(); final ProgressDialog pd = new ProgressDialog(this); pd.setMessage("正在缓冲..."); mediaPlayer.reset(); //设置播放的文件 mediaPlayer.setDataSource(et_path.getText().toString().trim()); mediaPlayer.prepare();//同步的准备 pd.show(); mediaPlayer.setOnErrorListener(new OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { Toast.makeText(MainActivity.this, "播放失败,错误代码:"+what, 0).show(); return false; } }); public void pause(View bf21 view) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.pause(); return; } if(mediaPlayer!=null){ mediaPlayer.start(); } } public void stop(View view) { if(mediaPlayer!=null){ mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } }
异步播放网络上的音乐文件
mediaPlayer.prepareAsync();//异步的准备,开启子线程去准备 mediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { pd.dismiss(); mediaPlayer.start(); } });
soundpool
打篮球的声音是用soundpool做的,不是mediaPlayerprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); soundPool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0); soundID = soundPool.load(this, R.raw.shoot, 1); } public void click(View view){ soundPool.play(soundID, 1.0f, 1.0f, 0, 0, 1.0f); }
视频播放器
protected void onCreate(Bundle savedInstanceState) { VideoView vv vv = (VideoView) findViewById(R.id.vv); vv.setVideoPath("/mnt/sdcard/oppo.3gp"); MediaController mc = new MediaController(this); //设置控制器 控制的是那一个videoview mc.setAnchorView(vv); //设置videoview的控制器为mc vv.setMediaController(mc); vv.start(); }
SurfaceView子线程更新ui
/** * 演示SurfaceView控件的使用 * SurfaceView 单位时间内完成界面的大量多次更新 * 双缓冲机制 : * A线程----更新ui -----后台计算---更新ui * B线程----后台计算----更新ui ---后台计算 * 可以在子线程更新ui */
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="click" android:text="开启子线程更新ui" /> <SurfaceView android:id="@+id/sv" android:layout_width="match_parent" android:layout_height="match_parent" />
surfaceview生命周期的回调
sv = (SurfaceView) findViewById(R.id.sv); //注册一个surfaceview控制器的回调 sv.getHolder().addCallback(new Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { System.out.println("surface被销毁了"); flag = false; } @Override public void surfaceCreated(SurfaceHolder holder) { System.out.println("surface创建了"); flag = true; new Thread(){ public void run() { for(int i = 0;i<100;i++){ if(!flag){ return ; } //界面里面内容显示的控制器 SurfaceHolder holder = sv.getHolder(); Canvas canvas = holder.lockCanvas(); canvas.drawColor(Color.BLACK); int radius = 5+i; Paint paint = new Paint(); paint.setColor(Color.RED); canvas.drawCircle(250, 250, radius, paint); holder.unlockCanvasAndPost(canvas); SystemClock.sleep(100); } }; }.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { System.out.println("surface大小发生了变化"); } });
采用surfaceview播放视频
<SurfaceView android:id="@+id/sv" android:layout_width="match_parent" android:layout_height="match_parent" />
@Override public void surfaceCreated(SurfaceHolder holder) { System.out.println("surface被创建"); try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource("/mnt/sdcard/oppo.3gp"); mediaPlayer.prepare(); } catch (Exception e) { e.printStackTrace(); } //指定多媒体的内容实在holder里面显示 mediaPlayer.setDisplay(holder); mediaPlayer.start(); mediaPlayer.seekTo(sp.getInt("position", 0)); } @Override public void surfaceDestroyed(SurfaceHolder holder) { System.out.println("surface被销毁"); if(mediaPlayer!=null){ int position = mediaPlayer.getCurrentPosition(); Editor editor = sp.edit(); editor.putInt("position", position); editor.commit(); mediaPlayer.stop(); mediaPlayer.release(); } }
照相机拍照
public void takePic(View view){ //开启手机的照相机应用拍照获取返回值 // create Intent to take a picture and return control to the calling application Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); file = new File(Environment.getExternalStorageDirectory(),SystemClock.uptimeMillis()+".jpg"); // create a file to save the image intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // set the image file name // start the image capture Intent startActivityForResult(intent, 0); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(file!=null&&file.exists()&&file.length()>0){ System.out.println(file.getAbsolutePath()); ImageView iv = (ImageView) findViewById(R.id.iv); iv.setImageURI(Uri.fromFile(file)); } super.onActivityResult(requestCode, resultCode, data); }
视频的录制
public void takePic(View view){ //开启手机的照相机应用拍照获取返回值 // create Intent to take a picture and return control to the calling application Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); file = new File(Environment.getExternalStorageDirectory(),SystemClock.uptimeMillis()+".3gp"); // create a file to save the image intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // set the image file name // start the image capture Intent startActivityForResult(intent, 0); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(file!=null&&file.exists()&&file.length()>0){ System.out.println(file.getAbsolutePath()); VideoView vv= (VideoView) findViewById(R.id.vv); vv.setVideoPath(file.getAbsolutePath()); MediaController mc = new MediaController(this); mc.setAnchorView(vv); vv.setMediaController(mc); vv.start(); } super.onActivityResult(requestCode, resultCode, data); }
传感器的使用
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sm = (SensorManager) getSystemService(SENSOR_SERVICE); //得到光传感器 Sensor sensor = sm.getDefaultSensor(Sensor.TYPE_LIGHT); listener = new MyListnener(); sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL); } private class MyListnener implements SensorEventListener{ //当传感器数据变化的调用的方法 @Override public void onSensorChanged(SensorEvent event) { float light = event.values[0]; System.out.println("光线强度:"+light); } //当传感器精度发生变化的时候调用的方法 @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } } @Override protected void onDestroy() { sm.unregisterListener(listener); listener = null; super.onDestroy(); }
指南针
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sm = (SensorManager) getSystemService(SENSOR_SERVICE); //得到方向传感器 Sensor sensor = sm.getDefaultSensor(3); listener = new MyListnener(); sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL); } private class MyListnener implements SensorEventListener{ //当传感器数据变化的调用的方法 @Override public void onSensorChanged(SensorEvent event) { //values[0]: 地磁北极和手机y轴的夹角, 0=北, 90=东, 180=南, 270=西 int angle = (int) event.values[0]; if(angle>0&&angle<90){ System.out.println("东北"); }else if (angle>90&&angle<180){ System.out.println("东南"); }else if(angle>180&&angle<270){ System.out.println("西南"); }else if(angle>270&&angle<360){ System.out.println("西北"); }else if(angle==0){ System.out.println("北"); }else if(angle==90){ System.out.println("东"); }else if(angle==180){ System.out.println("南"); }else if(angle==270){ System.out.println("西"); } } //当传感器精度发生变化的时候调用的方法 @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } } @Override protected void onDestroy() { sm.unregisterListener(listener); listener = null; super.onDestroy(); }
相关文章推荐
- Android11
- 蓝牙4.0BLE在安卓项目中的使用详解
- Android 横竖屏随意切换的两种方式
- Android Studio导入项目gradle报错,解决方案
- Android自定义控件之自定义倒计时按钮
- Android之查看手机实时电流、电压
- Android-验证手机上面是否存在其它应用接收Intent
- Android 应用的真正入口 - ZygoteInit.java
- Gradle系列第(三)篇---Android Studio与Gradle那些事儿
- android 用代码打开 gprs(流量开关) android 5.0 ROOT
- ViewGroup是如何加载布局中的view?
- Android逆向之旅---静态分析技术来破解Apk
- android studio 配置androidannotations注入框架
- Audroid-studio2.2安装1%与windows不兼容和Error occurred during initialization of VM 的问题
- Android 广播机制概论
- Android-Google提供的Activity生命周期图
- 安卓android_技术问题-Android下setLatestEventInfo警告、Handler警告、SimpleDateFormat警告
- Android进程间通信之使用Messenger
- Android源码的研究
- duplicate entry: android/support/annotation/ColorRes.class 打包时报错解答