位图_Android Studio学习笔记4
一、如何实现
1、创建一个自定义的View类
public class iView extends View{
public iView(Context context) {
super(context);
}
}
2、在OnCreat中把View添加到管理器中
FrameLayout framelayout = (FrameLayout) findViewById(R.id.framelayout);//我使用的是帧布局管理器
framelayout.addView(new iView(this));//把自定义的View添加到帧布局管理器中
3、在View里面重写onDraw方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
(打个onDraw+Enter就可以得到这一大坨了)
4、创建位图对象并显示
先创建一个数组,数组元素数值为颜色数值,然后用数组绘制一张位图
int i;
int[] color=new int[64*64];//大小为64*64
Matrix matrix=new Matrix();
Paint paint=new Paint();
----------------------------------------------
for(i=0;i<64*64;i++) {
color[i] = 0xFF3F51B5;//藏蓝色
}
@SuppressLint("DrawAllocation")
Bitmap picture=Bitmap.createBitmap(color,64,64,Bitmap.Config.RGB_565);//压缩格式为RGB565
canvas.drawBitmap(picture,matrix,paint);
5、保存位图
(1)MainActivity.java文件里
FileOutputStream fos=null;
------------------------------------
canvas.save();//保存canvas状态
canvas.restore();//恢复canvas保存状态
@SuppressLint("DrawAllocation")
File file = new File(Environment.getExternalStorageDirectory().getPath());
try {
fos=new FileOutputStream(file.getPath()+"/Pictures/tainanle.jpg");
picture.compress(Bitmap.CompressFormat.JPEG,100,fos);
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fos!=null)
{
try {
fos.close();
Toast.makeText(MainActivity.this,"图片保存成功", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(2)AndroidManifest.xml文件里添加写入数据权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
(3)运行时手机里该APP的存储权限也一定要打开!!!
附上代码:
【MainActivity.java】
package com.example.drawsave_s;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
int i;
int[] color=new int[64*64];
Matrix matrix=new Matrix();
Paint paint=new Paint();
FileOutputStream fos=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FrameLayout framelayout = (FrameLayout) findViewById(R.id.framelayout);
framelayout.addView(new iView(this));
}
public class iView extends View{
public iView(Context context) {
super(context);
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(i=0;i<64*64;i++) {
color[i] = 0xFF3F51B5;//藏蓝色
}
@SuppressLint("DrawAllocation")
Bitmap picture=Bitmap.createBitmap(color,64,64,Bitmap.Config.RGB_565);
canvas.drawBitmap(picture,matrix,paint);
canvas.save();
canvas.restore();
@SuppressLint("DrawAllocation")
File file = new File(Environment.getExternalStorageDirectory().getPath());
try {
fos=new FileOutputStream(file.getPath()+"/Pictures/tainanle.jpg");
picture.compress(Bitmap.CompressFormat.JPEG,100,fos);
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fos!=null)
{
try {
fos.close();
Toast.makeText(MainActivity.this,"图片保存成功", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
【AndroidManifest.xml】
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.drawsave_s">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.DrawSave_S">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
【activity_main.xml】
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingTop="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
tools:context=".MainActivity">
</FrameLayout>
二、需要注意的东西
1、颜色数组的数值与压缩格式无关
picture=Bitmap.createBitmap(color,64,64,Bitmap.Config.RGB_565);
我们在这里设置的Bitmap.Config.RGB_565是压缩后的格式RGB_565,与我们需要显示的颜色的格式是不同的,我们显示的依然是ARGB_8888.所以颜色的数值有8位。
位图通常都会进行压缩进行存储或显示,可以减小体积。一般对图像质量没有很高要求的用RGB565就很合适。
2、运行时手机里该APP的存储权限也一定要打开!!!
调试中发现当程序运行到try里面的
fos=new FileOutputStream(file.getPath()+"/Pictures/tainanle.jpg");
这句话的时候,就抛出异常,转入catch运行,那么就是在APP在手机上的存储权限没有打开。
3、创建路径时,前面的“/”一定要加上
三、补知识点
1、位图对象的创建
位图对象额创建有两个类,BitmapFactory类和Bitmap类
BitmapFactory类可以通过:
(1)decodeFile() 通过路径创建
(2)decodeResource() 通过ID资源创建
(3)decodeStream() 通过输入流创建
Bitmap类可以通过:
(1)creatBitmap() 通过重载形式创建
(2)creatScaledBitmap() 通过源位图的缩放创建
(3)compress() 压缩Bitmap对象并保存到文件输出流
2、存储方式
存储方式有4种:
(1)Shared Preference存储
(2)文件存储:
内部存储:存储在APP对应的包里,尽量不要保存在这里面
外部存储:存储在APP外手机中
(3)数据库存储 (词典操作)
(4)数据共享 (微信电话本)
该例程里用到的是外部存储
3、数组的创建
(1)创建一个长度为64的数组:
int[] data=new int[64];
(数组成员默认为0)
(2)创建一个长度为3的数组:
int[] data=new int[]{2,3,4};
4、try、catch、finally
语句逻辑:
如果try中的语句运行无异常,则执行try后执行finally;
如果try中的语句运行异常,则抛出错误转入运行catch中的语句后执行finally。