Android拍照或相册获取照片上传

本文介绍Android应用中如何实现从拍照和相册获取图片,并进行压缩处理,然后上传到服务器。通过onActivityResult回调获取图片路径,转换为需要的格式(如Bitmap、File或Stream),并提供完整代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现在的项目中越来越多的地方会用到上传图片的技术,比如im聊天,上传头像等。

那么android主要的获取图片的两种路径就是拍照和从相册获取。

今天就介绍下如何通过这两种途径获取,以及压缩获取到的图片并且写入文件上传到服务器。


1.打开相册

<pre name="code" class="java">intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(intent, OPEN_ALBUM_FLAG);

 


2.打开相机
//指定拍照后的输出路径
mSaveDir = Environment.getExternalStorageDirectory() + "/wyk_dir/";
File dir = new File(mSaveDir);
if (!dir.exists()) {
    dir.mkdir();
}
//指定拍取照片的名字(以时间戳命名,避免重复)
mFileName = "WYK" + String.valueOf(System.currentTimeMillis()) + ".jpg";
File file = new File(mSaveDir, mFileName);
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, OPEN_CAMERA_FLAG);
打开相册要做些特殊处理,需要先将图片保存的路径给设置好,便与之后的操作。之后就可以直接从该路径获取图片了。


3.压缩图片

private Bitmap getCompressBitmap(String path) {
    int BASE_SIZE = 400;//需要压缩到的最小宽高
    Bitmap bitmap;
    BitmapFactory.Options options = new BitmapFactory.Options();
    //只计算几何尺寸不返回bitmap,这样不会占用内存
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, options);

    int width = options.outWidth;
    int height = options.outHeight;
    int min = width < height ? width : height;
    int rate = min / BASE_SIZE;//压缩倍率
    if (rate < 1) rate = 1;
    options.inSampleSize = rate;
    options.inJustDecodeBounds = false;
    bitmap = BitmapFactory.decodeFile(path, options);
    return bitmap;
}
通过传入图片的路径获取压缩过的bitmap。从相册获取的图片,我们可以在回调中,通过查询本地数据获取uri路径;拍照获取的图片则根据我们之前设置的路径来获取。


4.处理onActivityResult回调

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    File file;
    Bitmap bitmap;
    OutputStream outputStream;

    if (resultCode == RESULT_OK) {
        switch (requestCode) {
            case OPEN_ALBUM_FLAG://从相册获取回调
                Uri originUri = data.getData();
                String[] proj = {MediaStore.Images.Media.DATA};
                Cursor cursor = managedQuery(originUri, proj, null, null, null);
                int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                String path = cursor.getString(columnIndex);
                bitmap = getCompressBitmap(path);
                mShowIV.setImageBitmap(bitmap);//将选中的图片展示出来
                /* 创建一个新的文件,存放压缩过的bitmap,用于发送给服务器 */
                String saveDir = Environment.getExternalStorageDirectory() + "/wyk_dir/";
                File dir = new File(saveDir);
                if (!dir.exists()) {
                    dir.mkdir();
                }
                //创建一个临时文件用来存放图片
                String fileName = "tmp.jpg";
                file = new File(saveDir, fileName);
                if (file.exists()) {
                    file.delete();
                }
                try {
                    file.createNewFile();
                    outputStream = new FileOutputStream(file);
                    //将bitmap写入file
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
                    System.out.println("file size:" + file.length());
                    /* 到这里已经成功将bitmap写入file了,此时可以将file或者流发送给服务器了 */
                } catch (Exception e) {
                    e.printStackTrace();
                }

                break;
            case OPEN_CAMERA_FLAG://拍照获取的回调
                file = new File(mSaveDir + mFileName);//拍照前指定的输出路径
                bitmap = getCompressBitmap(mSaveDir + mFileName);
                mShowIV.setImageBitmap(bitmap);//让拍照的照片显示在控件上
                try {
                    outputStream = new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
                    System.out.println("file size:" + file.length());
                    /* 到这里已经成功将bitmap写入file了,此时可以将file或者流发送给服务器了 */
                    break;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                break;
            default:
                break;
        }
    }

}

从相册或拍照获取的图片都会通过onActivityResult中的回调返回给你;两种途径返回都是一个文件路径,通过这个路径就可以获取到该图片的bitmap、file、stream等,具体需要什么就看和服务器的约定了,可以自行转换。



贴上完整代码,详细的讲解注释中有:


MainAvtivity.java

package com.yyl.uploadphototest;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class MainActivity extends Activity implements View.OnClickListener {
    private final int OPEN_ALBUM_FLAG = 1023;
    private final int OPEN_CAMERA_FLAG = 1024;

    private Button mAlbumBtn;//从相册获取照片
    private Button mCameraBtn;//拍照获取相片
    private ImageView mShowIV;
    private String mSaveDir;//拍照存放的文件夹名字
    private String mFileName;//拍照存放的文件的名字

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mAlbumBtn = (Button) findViewById(R.id.btn_album);
        mCameraBtn = (Button) findViewById(R.id.btn_camera);
        mShowIV = (ImageView) findViewById(R.id.iv_show);

        mAlbumBtn.setOnClickListener(this);
        mCameraBtn.setOnClickListener(this);


    }

    @Override
    public void onClick(View v) {
        Intent intent;
        switch (v.getId()) {
            case R.id.btn_album://相册获取
                intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                intent.setType("image/*");
                startActivityForResult(intent, OPEN_ALBUM_FLAG);
                break;
            case R.id.btn_camera://拍照获取
                //指定拍照后的输出路径
                mSaveDir = Environment.getExternalStorageDirectory() + "/wyk_dir/";
                File dir = new File(mSaveDir);
                if (!dir.exists()) {
                    dir.mkdir();
                }
                //指定拍取照片的名字(以时间戳命名,避免重复)
                mFileName = "WYK" + String.valueOf(System.currentTimeMillis()) + ".jpg";
                File file = new File(mSaveDir, mFileName);
                intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
                startActivityForResult(intent, OPEN_CAMERA_FLAG);

                break;
        }
    }

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    File file;
    Bitmap bitmap;
    OutputStream outputStream;

    if (resultCode == RESULT_OK) {
        switch (requestCode) {
            case OPEN_ALBUM_FLAG://从相册获取回调
                Uri originUri = data.getData();
                String[] proj = {MediaStore.Images.Media.DATA};
                Cursor cursor = managedQuery(originUri, proj, null, null, null);
                int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                String path = cursor.getString(columnIndex);
                bitmap = getCompressBitmap(path);
                mShowIV.setImageBitmap(bitmap);//将选中的图片展示出来
                /* 创建一个新的文件,存放压缩过的bitmap,用于发送给服务器 */
                String saveDir = Environment.getExternalStorageDirectory() + "/wyk_dir/";
                File dir = new File(saveDir);
                if (!dir.exists()) {
                    dir.mkdir();
                }
                //指定拍取照片的名字(以时间戳命名,避免重复)
                String fileName = "tmp.jpg";
                file = new File(saveDir, fileName);
                if (file.exists()) {
                    file.delete();
                }
                try {
                    file.createNewFile();
                    outputStream = new FileOutputStream(file);
                    //将bitmap写入file
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
                    System.out.println("file size:" + file.length());
                    /* 到这里已经成功将bitmap写入file了,此时可以将file或者流发送给服务器了 */
                } catch (Exception e) {
                    e.printStackTrace();
                }

                break;
            case OPEN_CAMERA_FLAG://拍照获取的回调
                file = new File(mSaveDir + mFileName);//拍照前指定的输出路径
                bitmap = getCompressBitmap(mSaveDir + mFileName);
                mShowIV.setImageBitmap(bitmap);//让拍照的照片显示在控件上
                try {
                    outputStream = new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
                    System.out.println("file size:" + file.length());
                    /* 到这里已经成功将bitmap写入file了,此时可以将file或者流发送给服务器了 */
                    break;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                break;
            default:
                break;
        }
    }

}

    /**
     * 一般相册或拍照的图片都很大,不会直接传给服务器,所以需要压缩
     *
     * @param path 图片的路径
     * @return 压缩后的图片
     */
    private Bitmap getCompressBitmap(String path) {
        int BASE_SIZE = 400;//需要压缩到的最小宽高
        Bitmap bitmap;
        BitmapFactory.Options options = new BitmapFactory.Options();
        //只计算几何尺寸不返回bitmap,这样不会占用内存
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        int width = options.outWidth;
        int height = options.outHeight;
        int min = width < height ? width : height;
        int rate = min / BASE_SIZE;//压缩倍率
        if (rate < 1) rate = 1;
        options.inSampleSize = rate;
        options.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(path, options);
        return bitmap;
    }
}



activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <Button
        android:id="@+id/btn_album"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="相册"/>

    <Button
        android:id="@+id/btn_camera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="拍照"/>

    <ImageView
        android:id="@+id/iv_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="centerCrop"
        android:maxHeight="300dp"
        android:maxWidth="300dp"/>

</LinearLayout><strong>
</strong>

有写的不对地方或者疑问欢迎在评论中提出~





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值