#android #android-camera-intent
#Android #android-camera-intent
Вопрос:
Я пытаюсь разрешить пользователю делать снимки со своей камеры и сохранять их внутри в памяти, и это работает. Проблема в том, что когда я пытаюсь изменить размер этого изображения, я создал метод и нашел способ добиться этого, но проблема в том, что onActivity возвращает только null для данных, поэтому я не могу получить к нему доступ
public void takePicture() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "App");
imagesFolder.mkdirs();
Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File image = new File(imagesFolder, "QR_" timeStamp ".jpg");
Uri uriSavedImage = Uri.fromFile(image);
uriString=uriSavedImage.toString();
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(imageIntent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE){
Uri uri =data.getData();
changeImageSize(uri,500,500);
}
}
private Bitmap changeImageSize(Uri fileUri, int width, int height) {
Bitmap bitmap = null;
File imgFile = new File(getRealPathFromURI(getApplicationContext(),fileUri));
if (imgFile.exists()) {
bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
}
if (bitmap != null) {
return bitmap = (Bitmap.createScaledBitmap(bitmap, width, height, false));
}
return null;
}
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = getActivity().getContentResolver().query(contentUri, null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":") 1);
cursor.close();
cursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,null
, MediaStore.Images.Media._ID " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
return path;
}
Я попытался добавить несколько решений, опубликованных ниже, и теперь я получаю сообщение об ошибке от моего метода getRealPathFromURI с указанием этого:
Logcat
Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference
java.lang.RuntimeException: Failure delivering result
ResultInfo{who=null, request=65636, result=-1, data=null} to activity {com.app/com.app.MainPostLogin}: java.lang.NullPointerException:
Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference
Комментарии:
1. что-то не так с вашим методом changeImageSize. пожалуйста, опубликуйте этот код
2. используйте путь к uri вашего хранилища в on activity, созданном следующим образом,
Uri uri = uriSavedImage; changeImageSize(uri,500,500);
3. некоторые устройства возвращают нулевые значения, поэтому попробуйте сделать это так.
4. Это звучит как логическое решение, но оно также выдает ошибку можете ли вы проверить обновленный вопрос
Ответ №1:
Когда вы передаете Uri в camera, он не возвращает никаких данных. Сохраните этот файл в локальной переменной File image = new File(imagesFolder, "QR_" timeStamp ".jpg");
и попробуйте
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE amp;amp; resultCode == RESULT_OK){
changeImageSize(Uri.fromFile(image),500,500);
}
}
Ответ №2:
Это рабочий код, который я использую в своем проекте для изменения размера изображения. Создайте этот метод (просто скопируйте и вставьте):
private String decodeFile(String path, int DESIREDWIDTH, int DESIREDHEIGHT) {
String strMyImagePath = null;
Bitmap scaledBitmap = null;
try {
// Part 1: Decode image
Bitmap unscaledBitmap = ScalingUtilities.decodeFile(path, DESIREDWIDTH, DESIREDHEIGHT, ScalingUtilities.ScalingLogic.FIT);
if (!(unscaledBitmap.getWidth() <= DESIREDWIDTH amp;amp; unscaledBitmap.getHeight() <= DESIREDHEIGHT)) {
// Part 2: Scale image
scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, DESIREDWIDTH, DESIREDHEIGHT, ScalingUtilities.ScalingLogic.FIT);
} else {
unscaledBitmap.recycle();
return path;
}
// Store to tmp file
String extr = Environment.getExternalStorageDirectory().toString();
File mFolder = new File(extr "/TMMFOLDER");
if (!mFolder.exists()) {
mFolder.mkdir();
}
String s = "tmp.png";
File f = new File(mFolder.getAbsolutePath(), s);
strMyImagePath = f.getAbsolutePath();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 75, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
scaledBitmap.recycle();
} catch (Throwable e) {
}
if (strMyImagePath == null) {
return path;
}
return strMyImagePath;
}
Создайте этот класс (просто скопируйте и вставьте):
package com.katariya.pomoc.utils;
/**
* Created by Danish.sharma on 5/31/2016.
*/
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
/**
* Class containing static utility methods for bitmap decoding and scaling
*
* @author
*/
public class ScalingUtilities {
/**
* Utility function for decoding an image resource. The decoded bitmap will
* be optimized for further scaling to the requested destination dimensions
* and scaling logic.
*
* @param res The resources object containing the image data
* @param resId The resource id of the image data
* @param dstWidth Width of destination area
* @param dstHeight Height of destination area
* @param scalingLogic Logic to use to avoid image stretching
* @return Decoded bitmap
*/
public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);
return unscaledBitmap;
}
public static Bitmap decodeFile(String path, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeFile(path, options);
return unscaledBitmap;
}
/**
* Utility function for creating a scaled version of an existing bitmap
*
* @param unscaledBitmap Bitmap to scale
* @param dstWidth Wanted width of destination bitmap
* @param dstHeight Wanted height of destination bitmap
* @param scalingLogic Logic to use to avoid image stretching
* @return New scaled bitmap object
*/
public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
dstWidth, dstHeight, scalingLogic);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
/**
* ScalingLogic defines how scaling should be carried out if source and
* destination image has different aspect ratio.
*
* CROP: Scales the image the minimum amount while making sure that at least
* one of the two dimensions fit inside the requested destination area.
* Parts of the source image will be cropped to realize this.
*
* FIT: Scales the image the minimum amount while making sure both
* dimensions fit inside the requested destination area. The resulting
* destination dimensions might be adjusted to a smaller size than
* requested.
*/
public static enum ScalingLogic {
CROP, FIT
}
/**
* Calculate optimal down-sampling factor given the dimensions of a source
* image, the dimensions of a destination area and a scaling logic.
*
* @param srcWidth Width of source image
* @param srcHeight Height of source image
* @param dstWidth Width of destination area
* @param dstHeight Height of destination area
* @param scalingLogic Logic to use to avoid image stretching
* @return Optimal down scaling sample size for decoding
*/
public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcWidth / dstWidth;
} else {
return srcHeight / dstHeight;
}
} else {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcHeight / dstHeight;
} else {
return srcWidth / dstWidth;
}
}
}
/**
* Calculates source rectangle for scaling bitmap
*
* @param srcWidth Width of source image
* @param srcHeight Height of source image
* @param dstWidth Width of destination area
* @param dstHeight Height of destination area
* @param scalingLogic Logic to use to avoid image stretching
* @return Optimal source rectangle
*/
public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.CROP) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
final int srcRectWidth = (int)(srcHeight * dstAspect);
final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
return new Rect(srcRectLeft, 0, srcRectLeft srcRectWidth, srcHeight);
} else {
final int srcRectHeight = (int)(srcWidth / dstAspect);
final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
return new Rect(0, scrRectTop, srcWidth, scrRectTop srcRectHeight);
}
} else {
return new Rect(0, 0, srcWidth, srcHeight);
}
}
/**
* Calculates destination rectangle for scaling bitmap
*
* @param srcWidth Width of source image
* @param srcHeight Height of source image
* @param dstWidth Width of destination area
* @param dstHeight Height of destination area
* @param scalingLogic Logic to use to avoid image stretching
* @return Optimal destination rectangle
*/
public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
} else {
return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
}
} else {
return new Rect(0, 0, dstWidth, dstHeight);
}
}
}
Это основная строка для изменения размера изображения
Bitmap bmp = BitmapFactory.decodeFile(decodeFile(file.toString(), 600, 600));
imageView.setImageBitmap(bmp);
Смотрите мой onActivityResult как и где я использую эти строки:
@Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST) {
new Thread(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
try {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory() "/Guesp");
if (!destination.exists()) {
File f = new File("/sdcard/POMOC/");
f.mkdir();
}
File file = new File(new File("/sdcard/POMOC/"), System.currentTimeMillis() ".jpg");
FileOutputStream fo;
try {
file.createNewFile();
fo = new FileOutputStream(file);
fo.write(bytes.toByteArray());
fo.close();
picturePath = file.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bmp = BitmapFactory.decodeFile(decodeFile(file.toString(), 600, 600));
img_profilePhoto.setImageBitmap(bmp);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}).start();
}
}
Вот и все.