Android关于图片的处理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android关于图片的处理相关的知识,希望对你有一定的参考价值。

一、布局中显示图片
在布局的xml中布局图片的时候用ImageView,用src去指定图片所在位置。如下代码所示,指定的就是工程目录(/res/drawable)中文件名为unknown.png的图片。
这里要注意的是android Studio在布局时只认png格式的图片,即使是jpeg格式,仅把后缀改为png也不行,编译时会不通过。

<ImageView 
                android:id="@+id/iv_mytest"
                android:src="@drawable/unknown" />

但是,也不等于jpeg格式的图片就不能显示,我们可以通过如下代码处理的方式来展示到界面上。

String imgPath = Environment.getExternalStorageDirectory() + "test.jpg";
ImageView iv_mytest = (ImageView) findViewById(R.id.iv_mytest);
iv_mytest.setVisibility(View.VISIBLE);
if(!imgPath.equals("")) {
        Bitmap tempBitmap = BitmapFactory.decodeFile(imgPath);
        iv_mytest.setImageBitmap(tempBitmap);//显示图片
}

二、拍照后显示图片
拍照流程为获取缓存图片路径->进入拍照界面->拍照界面拍照后自动存到缓存图片路径中->进入回调函数->对缓存图片进行处理(如旋转缩放等)并存储到自己指定位置->删除缓存路径图片。
具体代码如下所示:

private String tmpfilename = "";
//调用拍照界面
private void photograph(){
        try {
                // 跳转至拍照界面
                String sdStatus = Environment.getExternalStorageState();
                if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
                        ToastUtil.showToastMsgError(MyTestActivity.this,"SD card is not avaiable/writeable right now.");
                        return;
                }

                tmpfilename=getTempFilePath();
                File out = new File(tmpfilename);

                Intent intentPhote = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intentPhote.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
                Uri uri = Uri.fromFile(out);
                // 获取拍照后未压缩的原图片,并保存在uri路径中
                intentPhote.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                startActivityForResult(intentPhote, 1);
        }catch (Exception e) {

        }
}

/**
 * 获取原缓存图片存储路径
 * @return
 */
private String getTempFilePath() {
        // 照片全路径
        String fileName = "";
        // 文件夹路径
        String pathUrl = Environment.getExternalStorageDirectory()+"/tmp/";

        imagename = "mytest.png";
        File file = new File(pathUrl);
        file.mkdirs();// 创建文件夹
        fileName = pathUrl + imagename;
        return fileName;
}

//拍取照后的回调
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true; // 设置了此属性一定要记得将值设置为false
                Bitmap bitmap = BitmapFactory.decodeFile(tmpfilename);
                // 防止OOM发生
                options.inJustDecodeBounds = false;
                saveMyBitmap(imagename,bitmap);

                File old = new File(Environment.getExternalStorageDirectory() + "/tmp/");
                FileUtil.deleteFile(old);//删除缓存图片

                String resultMsg = "图片已保存";
                ToastUtil.showToastMsgSuccess(this, resultMsg);
        }
}

//将图像保存到SD卡中
public void saveMyBitmap(String bitName, Bitmap mBitmap) {
        String thisDate = formatter_date.format(new Date());
        File f = FileUtil.getFilePath(Environment.getExternalStorageDirectory() + "/rfid/prehairpin/"+thisDate+"/", bitName);
        String realfilepath = f.getPath();
        FileOutputStream fOut = null;
        try {
                fOut = new FileOutputStream(f);
        } catch (Exception e) {
                e.printStackTrace();
        }

        Matrix matrix = new Matrix();

        // 按照固定大小对图片进行缩放
        matrix.postScale(0.3f, 0.3f);
        System.out.println(mBitmap.getWidth() + mBitmap.getHeight());
        if (mBitmap.getHeight() < mBitmap.getWidth()) {
                matrix.postRotate(90);  //翻转90度
        }
        mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
        mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);

        try {
                fOut.write(("my secret message").getBytes());//我在这边偷偷给图片结尾藏了一些信息
                fOut.flush();
        } catch (IOException e) {
                e.printStackTrace();
        }
        try {
                fOut.close();
        } catch (IOException e) {
                e.printStackTrace();
        }
}

三、图片的处理
旋转、缩放等操作我们是通过Matrix来处理的,Matrix还有很多其他图形处理的方法,可以另开一篇去讲述。

Matrix matrix = new Matrix();
// 按照固定大小对图片进行缩放
matrix.postScale(0.3f, 0.3f);
if (mBitmap.getHeight() < mBitmap.getWidth()) {
        matrix.postRotate(90);  //翻转90度
}
mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);

保存图片,并将字符存入图片(有时候拍照后希望将一些信息与图片绑定起来,直接记录文件名又担心被人篡改,就想到了这种在图片文件末尾记录一些信息的方式)

String thisDate = formatter_date.format(new Date());
File f = FileUtil.getFilePath(Environment.getExternalStorageDirectory() + "/rfid/prehairpin/"+thisDate+"/", bitName);
String realfilepath = f.getPath();
FileOutputStream fOut = null;
try {
        fOut = new FileOutputStream(f);
} catch (Exception e) {
        e.printStackTrace();
}
//我在这边偷偷给图片结尾藏了一些信息
try {
        fOut.write(("my secret message").getBytes());
        fOut.flush();
} catch (IOException e) {
        e.printStackTrace();
}
try {
        fOut.close();
} catch (IOException e) {
        e.printStackTrace();
}

四、图片格式的差异
png、jpeg因为格式的差异,在内部添加字符信息时会不一样,比如png格式结尾处就是图片信息,所以添加的话直接在末尾添加就可以;而jpeg不行,jpeg末尾是有固定格式信息的,直接加载末尾虽然不影响图片显示,但是在解析时就会因为位置偏移解析出来的字符信息就不对了。
这一块内容还有待去深入研究下,当时也只是试验了两种格式,发现了这一问题。

以上是关于Android关于图片的处理的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中使用片段时处理后按

是否有在单个活动中处理多个片段的 Android 设计模式?

可折叠工具栏 - 使片段页脚在 Android 中始终可见

我的Android进阶之旅关于Android平台获取文件的mime类型:为啥不传小写后缀名就获取不到mimeType?为啥android 4.4系统获取不到webp格式的mimeType呢?(代码片段

我的Android进阶之旅关于Android平台获取文件的mime类型:为啥不传小写后缀名就获取不到mimeType?为啥android 4.4系统获取不到webp格式的mimeType呢?(代码片段

关于android屏幕适配的问题(drawable-xxxxxxxx,dp,sp,px等等),偶尔看到了android源代码,关于dpi的区分的值