拍摄后的图片处理
Posted
技术标签:
【中文标题】拍摄后的图片处理【英文标题】:Picture manipulation after capture 【发布时间】:2015-04-19 19:24:54 【问题描述】:如果您足够友善,我需要您的帮助来解决我在使用 android 应用时遇到的问题:
我已经设法在我的 MainActivity 中捕获了一张图片并将其显示到一个单独的活动中 - PictureActivity。我的代码如下:
在我的 MainActivity 我有
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
/**
* This is called in tap on a graphic element in my MainActivity layout
*/
public void launchCamera(View v)
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
Bitmap imageData = null;
if (resultCode == RESULT_OK)
imageData = (Bitmap) data.getExtras().get("data");
Intent i = new Intent(this, PictureActivity.class);
i.putExtra("captured_picture", imageData);
startActivity(i);
else if (resultCode == RESULT_CANCELED)
// User cancelled the image capture
else
Toast.makeText(getApplicationContext(), R.string.picture_capture_error, Toast.LENGTH_SHORT).show();
我的 PictureActivity 如下所示:
public class PictureActivity extends ActionBarActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_picture);
Bitmap bitmap = getIntent().getExtras().getParcelable("captured_picture");
ImageView view = (ImageView) findViewById(R.id.preview_photo);
view.setImageBitmap(bitmap);
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.image_menu, menu);
return true;
@Override
public boolean onOptionsItemSelected(MenuItem item)
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
return super.onOptionsItemSelected(item);
我的 PictureActivity 布局看起来像这样
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_
android:layout_>
<ImageView
android:id="@+id/preview_photo"
android:layout_
android:layout_ />
</LinearLayout>
这是目前为止的最终结果:
长话短说,接下来是我想做的事情:
如果用户点击主操作栏中的中间按钮,则旋转图片 如果用户点击左起第一个按钮,则裁剪图片接下来,将图像保存在某处(可能是在共享首选项或会话中?),然后,将其上传到远程服务器。我说“将图像保存在某处”是因为用户可以选择拍摄第二张照片(最多两张)并在上面执行相同的操作(通过点击第一个按钮从右侧开始,在主操作栏中)。
到目前为止,我无法弄清楚的是:
我如何知道当前图像(我在屏幕上看到的)是什么 在将其上传到远程服务器之前,如何设置它的名称和保存位置 当我点击两个按钮之一(crop 或 rotate)时,如何操作它抱歉发了这么长的帖子,提前感谢您的帮助!
【问题讨论】:
【参考方案1】:回答您的 3 个问题:
-
您看到的当前图像在您的设备 RAM 中。它是保存数据的位图对象。
您必须将位图保存到您的设备存储中
您必须先转换位图,然后再将其保存到存储中
这里有一些可能对你有帮助的代码:
public static void saveBitmapToFile(Bitmap bitmap, String filename)
FileOutputStream out = null;
try
out = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
catch (Exception e)
e.printStackTrace();
finally
try
if (out != null)
out.close();
catch (IOException e)
e.printStackTrace();
public static Bitmap cropAndRotateBitmap(Bitmap bitmap, Rect cropRect, int rotateByDegrees)
Log.v(TAG, "cropAndRotateBitmap()");
Log.v(TAG, "bitmap: " + bitmap);
//Log.v(TAG, "orientation: " + orientation);
Log.v(TAG, "degrees: " + rotateByDegrees);
Log.v(TAG, "cropRect: " + cropRect);
int cropRectWidth = cropRect.right - cropRect.left;
int cropRectHeight = cropRect.bottom - cropRect.top;
System.gc();
Bitmap result;
Matrix m = new Matrix();
Canvas canvas = new Canvas();
if (rotateByDegrees == 0)
result = Bitmap.createBitmap(cropRectWidth, cropRectHeight, Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
m.postTranslate(-cropRect.left, -cropRect.top);
else if (rotateByDegrees == 90)
Log.v(TAG, "rotate 90, cropRect: " + cropRect);
result = Bitmap.createBitmap(cropRectHeight, cropRectWidth, Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
m.postTranslate(-cropRect.left, -cropRect.height() - cropRect.top);
m.postRotate(90);
else if (rotateByDegrees == 180)
Log.v(TAG, "rotate 180");
result = Bitmap.createBitmap(cropRectWidth, cropRectHeight, Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
m.postTranslate(-cropRect.left - cropRect.width(), -cropRect.height() - cropRect.top);
m.postRotate(180);
else // 270
Log.v(TAG, "rotate 270");
result = Bitmap.createBitmap(cropRectHeight, cropRectWidth, Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
m.postTranslate(-cropRect.width() - cropRect.left, -cropRect.top);
m.postRotate(270);
Paint whitePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
whitePaint.setStyle(Paint.Style.FILL);
whitePaint.setColor(Color.WHITE);
canvas.drawBitmap(bitmap, m, whitePaint);
// canvas.restore();
return result;
public static Bitmap rotateBitmap(Bitmap bitmap, int rotateByDegrees)
Log.v(TAG, "rotateBitmap()");
Log.v(TAG, "degrees: " + rotateByDegrees);
System.gc();
Bitmap result;
Canvas canvas = new Canvas();
if (rotateByDegrees == 0)
result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
canvas.save();
else if (rotateByDegrees == 90)
result = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
canvas.save();
canvas.rotate(90);
canvas.translate(0, -1 * bitmap.getHeight());
else if (rotateByDegrees == 180)
result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
canvas.save();
canvas.rotate(180);
canvas.translate(-1 * bitmap.getWidth(), -1 * bitmap.getHeight());
else // 270
result = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
canvas.save();
canvas.rotate(270);
canvas.translate(-1 * bitmap.getWidth(), 0);
canvas.drawBitmap(bitmap, new Matrix(), null);
canvas.restore();
return result;
【讨论】:
以上是关于拍摄后的图片处理的主要内容,如果未能解决你的问题,请参考以下文章