源码:TakePhoto.7z
功能实现:
photo_layout.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/button_select"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="上传"
android:onClick="SelectPhoto"/>
<Button
android:id="@+id/button_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="拍照"
android:onClick="TakePhoto"/>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_launcher" />
</LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.takephoto"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="19" />
<uses-feature android:name="android.harware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="TakePhoto" >
<activity
android:name="com.example.MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java
package com.example;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.widget.ImageView;
import com.example.takephoto.R;
import com.example.tool.PhotoActivity;
/** MainActivity.java: ----- 2018-6-19 下午4:23:59 */
public class MainActivity extends PhotoActivity
{
ImageView image;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.photo_layout);
image = (ImageView) this.findViewById(R.id.imageView);
}
/** 选择或拍照获取的图像 */
@Override
public void PhotoResult(Bitmap bitmap)
{
// String picData = BitmapTool.ToString(bitmap); // 转化为字符串形式,存储至服务器端
// bitmap = BitmapTool.ToBitmap(picData); // 从字符串数据,还原为Bitmap
if (bitmap != null) image.setImageBitmap(bitmap); // 显示图像
}
}
package com.example.tool;
import java.io.File;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.view.View;
import android.widget.Toast;
/**
// 用法:继承自此Activity
// 选择图像调用:SelectPhoto(View view)、拍照调用:TakePhoto(View view)
// 获取图像重写:PhotoResult(Bitmap bitmap); ——进行图像上传或显示
*/
public abstract class PhotoActivity extends Activity /* AppCompatActivity */
{
// ImageView image;
// protected void onCreate(Bundle savedInstanceState)
// {
// super.onCreate(savedInstanceState);
//
// // setContentView(R.layout.photo_layout);
// // image = (ImageView) this.findViewById(R.id.imageView);
// }
// 选择图像
public void SelectPhoto(View view)
{
try
{
PhotoTool.SelectPicture(this);
}
catch (Exception ex)
{
}
}
// 拍照
public void TakePhoto(View view)
{
try
{
photoPath = PhotoTool.TakePhoto(this); // 获取拍照图像路径
}
catch (Exception ex)
{
Toast.makeText(this, "不支持拍照", Toast.LENGTH_SHORT).show();
}
}
// 最终获取的图像
public abstract void PhotoResult(Bitmap bitmap);
// {
// String picData = BitmapTool.ToString(bitmap); // 转化为字符串形式,存储至服务器端
// bitmap = BitmapTool.ToBitmap(picData); // 从字符串数据,还原为Bitmap
// if (bitmap != null) image.setImageBitmap(bitmap); // 显示图像
// }
// // 选择图像
// public void SelectPhoto(View view)
// {
// String[] permissions = new String[] { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE };
//
// if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
// || ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
// {
// ActivityCompat.requestPermissions(this, permissions, MY_PERMISSIONS_REQUEST_SELECT_PHOTO);
// }
// else
// {
// PhotoUtil.selectPictureFromAlbum(this); // 从手机中选择图像
// }
// }
// // 拍照
// public void TakePhoto(View view)
// {
// String[] permissions = new String[] { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA
// };
//
// if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
// || ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
// || ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
// {
// ActivityCompat.requestPermissions(this, permissions, MY_PERMISSIONS_REQUEST_TAKE_PHOTO);
// }
// else
// {
// photoPath = PhotoUtil.photograph(this); // 获取拍照图像路径
// }
// }
String photoPath = ""; // 拍照获得的图像路径
String outPath = "";
int Height = 300;
int Width = 300;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
// 对拍照获得的图像进行裁切处理
if (requestCode == PhotoTool.RES_TakePhoto)
{
if (!photoPath.equals(""))
{
// 对拍照获得的图像进行裁切
Uri sourceImage = Uri.fromFile(new File(photoPath));
outPath = PhotoTool.startPhotoZoom(this, sourceImage, Height, Width);
}
}
// 对选取的图像进行裁切处理
if (requestCode == PhotoTool.RES_ProccessPhoto)
{
if (intent == null) return;
outPath = PhotoTool.startPhotoZoom(this, intent.getData(), Height, Width);
}
// 显示/上传 最终图像 处理逻辑
if (requestCode == PhotoTool.RES_Photo)
{
// 缩放图像
if (new File(outPath).exists())
{
Bitmap bitmap = BitmapTool.ReSizeBitmap(outPath, Height, Width);
bitmap = BitmapTool.CircleProcess(bitmap); // 转化为圆形图像
PhotoResult(bitmap);
// String picData = BitmapTool.ToString(bitmap); // 转化为字符串形式,存储至服务器端
// bitmap = BitmapTool.ToBitmap(picData); // 从字符串数据,还原为Bitmap
// if (bitmap != null) image.setImageBitmap(bitmap); // 显示图像
}
}
super.onActivityResult(requestCode, resultCode, intent);
}
// private static final int MY_PERMISSIONS_REQUEST_SELECT_PHOTO = 1;
// private static final int MY_PERMISSIONS_REQUEST_TAKE_PHOTO = 2;
//
// @Override
// public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
// {
// if (requestCode == MY_PERMISSIONS_REQUEST_SELECT_PHOTO)
// {
// if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED)
// {
// PhotoUtil.selectPictureFromAlbum(this);
// }
// else
// {
// Toast.makeText(this, "无存储权限,无法选择图像", Toast.LENGTH_SHORT).show();
// }
// }
//
// if (requestCode == MY_PERMISSIONS_REQUEST_TAKE_PHOTO)
// {
// if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED
// && grantResults[2] == PackageManager.PERMISSION_GRANTED)
// {
// photoPath = PhotoUtil.photograph(this); // 拍照,获取图像路径
// }
// else
// {
// Toast.makeText(this, "需要要相机和存储权限,才能拍照", Toast.LENGTH_SHORT).show();
// }
// }
//
// super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// }
}
package com.example.tool;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
public class PhotoTool
{
public static final int NONE = 0;
public static final String IMAGE_UNSPECIFIED = "image/*";// 任意图片类型
public static final int RES_TakePhoto = 1; // 拍照
public static final int RES_ProccessPhoto = 2; // 缩放
public static final int RES_Photo = 3; // 最终图像
/** 从系统相册中选取照片上传 */
public static void SelectPicture(Activity activity)
{
// 调用系统的相册
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);
// 选择图像后调用activity.onActivityResult:RES_ProccessPhoto逻辑
activity.startActivityForResult(intent, RES_ProccessPhoto);
}
// /** 从系统相册中选取照片上传 */
// public static void selectPictureFromAlbum(Fragment fragment)
// {
// // 调用系统的相册
// Intent intent = new Intent(Intent.ACTION_PICK, null);
// intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);
//
// // 调用剪切功能
// fragment.startActivityForResult(intent, PHOTOZOOM);
// }
/** 拍照 */
public static String TakePhoto(Activity activity)
{
String outPicPath = getPath(activity);
// 调用系统的拍照功能
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(outPicPath)));
// 拍照后调用activity.onActivityResult:RES_TakePhoto逻辑
activity.startActivityForResult(intent, RES_TakePhoto);
return outPicPath;
}
// /** 拍照 */
// public static void photograph(Fragment fragment)
// {
// imageName = "/" + getStringToday() + ".jpg";
//
// // 调用系统的拍照功能
// Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// String status = Environment.getExternalStorageState();
// if (status.equals(Environment.MEDIA_MOUNTED))
// {
// intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), imageName)));
// }
// else
// {
// intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(fragment.getActivity().getFilesDir(), imageName)));
// }
// fragment.startActivityForResult(intent, PHOTOGRAPH);
// }
// /** 图片裁剪 */
// public static void startPhotoZoom(Activity activity, Uri uri, int height, int width)
// {
// Intent intent = new Intent("com.android.camera.action.CROP");
// intent.setDataAndType(uri, IMAGE_UNSPECIFIED);
// intent.putExtra("crop", "true");
// // aspectX aspectY 是宽高的比例
// intent.putExtra("aspectX", 1);
// intent.putExtra("aspectY", 1);
// // outputX outputY 是裁剪图片宽高
// intent.putExtra("outputX", height);
// intent.putExtra("outputY", width);
// intent.putExtra("noFaceDetection", true); // 关闭人脸检测
// intent.putExtra("return-data", true);// 如果设为true则返回bitmap
// intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);// 输出文件
// intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
// activity.startActivityForResult(intent, PHOTORESOULT);
// }
/** 图片裁剪
*
* @param activity
* @param uri 原图的地址
* @param height 指定的剪辑图片的高
* @param width 指定的剪辑图片的宽
* @param 返回 剪辑后的图片路径 */
public static String startPhotoZoom(Activity activity, Uri uri, int height, int width)
{
String outPicPath = getPath(activity);
Uri destUri = Uri.fromFile(new File(outPicPath));
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, IMAGE_UNSPECIFIED);
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", height);
intent.putExtra("outputY", width);
intent.putExtra("noFaceDetection", true); // 关闭人脸检测
intent.putExtra("return-data", false);// 如果设为true则返回bitmap
intent.putExtra(MediaStore.EXTRA_OUTPUT, destUri);// 输出文件
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
// 图像裁切后调用activity.onActivityResult:RES_Photo逻辑
activity.startActivityForResult(intent, RES_Photo);
return outPicPath;
}
// /** 图片裁剪 */
// public static void startPhotoZoom(Fragment fragment, Uri uri, int height, int width)
// {
// Intent intent = new Intent("com.android.camera.action.CROP");
// intent.setDataAndType(uri, IMAGE_UNSPECIFIED);
// intent.putExtra("crop", "true");
// // aspectX aspectY 是宽高的比例
// intent.putExtra("aspectX", 1);
// intent.putExtra("aspectY", 1);
// // outputX outputY 是裁剪图片宽高
// intent.putExtra("outputX", height);
// intent.putExtra("outputY", width);
// intent.putExtra("return-data", true);
// fragment.startActivityForResult(intent, PHOTORESOULT);
// }
// ----------------------------------------
// 相关功能函数
// ----------------------------------------
/** 获取当前系统时间并格式化 */
@SuppressLint("SimpleDateFormat")
public static String getStringToday()
{
Date currentTime = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
String dateString = formatter.format(currentTime);
return dateString;
}
/** 制作图片的路径地址 */
public static String getPath(Context context)
{
// 获取系统路径
String RootDir = context.getFilesDir().toString();
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
{
RootDir = Environment.getExternalStorageDirectory().toString();
}
// 创建文件夹
String path = RootDir + File.separator + "takePhoto/";
File file = new File(path);
if (!file.exists()) file.mkdirs();
// 生成新的文件名
String filePath = path + getStringToday() + ".jpg";
return filePath;
}
/** 文件路径转化为Uri */
public static Uri ToUri(String filePath)
{
return Uri.fromFile(new File(filePath));
}
}
package com.example.tool;
import java.io.ByteArrayOutputStream;
import java.lang.ref.WeakReference;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.util.Base64;
/** BitmapTool.java: ----- 2018-6-14 下午3:59:35 */
public class BitmapTool
{
/** 图片转string */
public static String ToString(Bitmap bitmap)
{
ByteArrayOutputStream outStream = new ByteArrayOutputStream(); // outputstream
bitmap.compress(CompressFormat.PNG, 100, outStream); // 保存图像到输出流中
byte[] bytes = outStream.toByteArray(); // 转为byte数组
return Base64.encodeToString(bytes, Base64.DEFAULT); // Base64编码数组
}
/** string数据转bitmap */
public static Bitmap ToBitmap(String bitmapData)
{
Bitmap bitmap = null;
try
{
// out = new FileOutputStream("/sdcard/aa.jpg");
byte[] bitmapArray = Base64.decode(bitmapData, Base64.DEFAULT);
bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length);
// bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
return bitmap;
}
catch (Exception e)
{
return null;
}
}
/** Drawable数据转Bitmap */
public static Bitmap ToBitmap(Drawable drawable)
{
// 取 drawable 的长宽
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
// 取 drawable 的颜色格式
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
// 建立对应 bitmap
Bitmap bitmap = Bitmap.createBitmap(w, h, config);
// 建立对应 bitmap 的画布
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
// 把 drawable 内容画到画布中
drawable.draw(canvas);
return bitmap;
}
/** Bitmap数据转Drawable */
public static Drawable ToDrawable(Bitmap bitmap)
{
Drawable drawable = new BitmapDrawable(bitmap);
return drawable;
}
/** 按指定大小载入bitmap */
public static Bitmap ReSizeBitmap(String path, int w, int h)
{
BitmapFactory.Options opts = new BitmapFactory.Options();
// 设置为ture只获取图片大小
opts.inJustDecodeBounds = true;
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
BitmapFactory.decodeFile(path, opts);
int width = opts.outWidth;
int height = opts.outHeight;
float scaleWidth = 0.f, scaleHeight = 0.f;
if (width > w || height > h)
{
// 缩放
scaleWidth = ((float) width) / w;
scaleHeight = ((float) height) / h;
}
opts.inJustDecodeBounds = false;
float scale = Math.max(scaleWidth, scaleHeight);
opts.inSampleSize = (int) scale;
WeakReference<Bitmap> weak = new WeakReference<Bitmap>(BitmapFactory.decodeFile(path, opts));
return Bitmap.createScaledBitmap(weak.get(), w, h, true);
}
/** bitmap转化为圆形,剔除圆圈外像素 */
public static Bitmap CircleProcess(Bitmap pic)
{
int W = pic.getWidth();
int H = pic.getWidth();
int R = ((W < H) ? W : H) / 2;
int x0 = W / 2;
int y0 = H / 2;
Bitmap tmp = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
int colorTrans = Color.parseColor("#00ffffff");
for (int h = 0; h < pic.getHeight(); h++)
{
for (int w = 0; w < pic.getWidth(); w++)
{
int pix = pic.getPixel(w, h);
int N = (w - x0) * (w - x0) + (h - y0) * (h - y0);
if (N > R * R)
tmp.setPixel(w, h, colorTrans); // 超出半径范围,清空像素
else tmp.setPixel(w, h, pix); // 复制像素
}
}
return tmp;
}
// /** 获取原图bitmap */
// public static Bitmap convertToBitmap2(String path)
// {
// BitmapFactory.Options opts = new BitmapFactory.Options();
// // 设置为ture只获取图片大小
// opts.inJustDecodeBounds = true;
// opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
// // 返回为空
// BitmapFactory.decodeFile(path, opts);
// return BitmapFactory.decodeFile(path, opts);
// }
}