ฉันต้องการเขียนโมดูลที่คลิกปุ่มเปิดกล้องและฉันสามารถคลิกและจับภาพ หากฉันไม่ชอบภาพฉันสามารถลบมันแล้วคลิกอีกหนึ่งภาพจากนั้นเลือกภาพและควรกลับไปและแสดงภาพนั้นในกิจกรรม
ฉันต้องการเขียนโมดูลที่คลิกปุ่มเปิดกล้องและฉันสามารถคลิกและจับภาพ หากฉันไม่ชอบภาพฉันสามารถลบมันแล้วคลิกอีกหนึ่งภาพจากนั้นเลือกภาพและควรกลับไปและแสดงภาพนั้นในกิจกรรม
คำตอบ:
นี่คือกิจกรรมตัวอย่างที่จะเปิดแอพกล้องถ่ายรูปจากนั้นดึงภาพและแสดง
package edu.gvsu.cis.masl.camerademo;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class MyCameraActivity extends Activity
{
private static final int CAMERA_REQUEST = 1888;
private ImageView imageView;
private static final int MY_CAMERA_PERMISSION_CODE = 100;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.imageView = (ImageView)this.findViewById(R.id.imageView1);
Button photoButton = (Button) this.findViewById(R.id.button1);
photoButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_PERMISSION_CODE);
}
else
{
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_CAMERA_PERMISSION_CODE)
{
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this, "camera permission granted", Toast.LENGTH_LONG).show();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
else
{
Toast.makeText(this, "camera permission denied", Toast.LENGTH_LONG).show();
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK)
{
Bitmap photo = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(photo);
}
}
}
โปรดทราบว่าแอพกล้องถ่ายรูปช่วยให้คุณสามารถตรวจสอบ / ถ่ายภาพอีกครั้งและเมื่อยอมรับภาพแล้วกิจกรรมจะแสดงขึ้นมา
นี่คือเค้าโครงที่กิจกรรมข้างต้นใช้ มันเป็น LinearLayout ที่ประกอบด้วยปุ่มที่มี id button1 และ ImageView พร้อม id imageview1:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/photo"></Button>
<ImageView android:id="@+id/imageView1" android:layout_height="wrap_content" android:src="@drawable/icon" android:layout_width="wrap_content"></ImageView>
</LinearLayout>
และรายละเอียดสุดท้ายให้แน่ใจว่าได้เพิ่ม:
<uses-feature android:name="android.hardware.camera"></uses-feature>
และถ้ากล้องเป็นอุปกรณ์เสริมสำหรับฟังก์ชั่นแอปของคุณ ตรวจสอบให้แน่ใจว่าจำเป็นต้องตั้งค่าเป็นเท็จในการอนุญาต แบบนี้
<uses-feature android:name="android.hardware.camera" android:required="false"></uses-feature>
เพื่อ manifest.xml ของคุณ
<uses-feature/>
กับandroid:required="false"
แอตทริบิวต์:<uses-feature android:name="android.hardware.camera" android:required="false"></uses-feature>
Bitmap photo = (Bitmap) data.getExtras().get("data");
ไม่จับภาพที่ถ่าย มันคว้าภาพขนาดย่อของภาพที่ถ่าย
Google ได้เพิ่มActivityResultRegistry
API ใหม่ที่"ช่วยให้คุณจัดการstartActivityForResult()
+ onActivityResult()
รวมถึงrequestPermissions()
+ onRequestPermissionsResult()
โฟลว์โดยไม่ต้องใช้วิธีการแทนที่ในกิจกรรมหรือชิ้นส่วนของคุณเพิ่มความปลอดภัยของประเภทที่เพิ่มขึ้นผ่านActivityResultContract
และมอบตะขอสำหรับทดสอบกระแสเหล่านี้" - แหล่งที่มาแหล่งที่มา
API ที่ถูกเพิ่มเข้ามาในandroidx.activity 1.2.0-alpha02และandroidx.fragment 1.3.0-alpha02
ดังนั้นตอนนี้คุณสามารถทำสิ่งที่ชอบ:
val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { success: Boolean ->
if (success) {
// The image was saved into the given Uri -> do something with it
}
}
val imageUri: Uri = ...
button.setOnClickListener {
takePicture.launch(imageUri)
}
ดูเอกสารประกอบเพื่อเรียนรู้วิธีใช้ API ผลกิจกรรมใหม่: https://developer.android.com/training/basics/intents/result#kotlin
มีActivityResultContractsในตัวหลายตัวที่ให้คุณทำสิ่งต่าง ๆ เช่นเลือกผู้ติดต่อร้องขอสิทธิ์ถ่ายภาพหรือถ่ายวิดีโอ คุณอาจสนใจในActivityResultContracts.TakePicture ที่แสดงด้านบน
โปรดทราบว่าandroidx.fragment 1.3.0-alpha04ไม่รองรับstartActivityForResult()
+ onActivityResult()
และrequestPermissions()
+ onRequestPermissionsResult()
APIs บน Fragment ดังนั้นจึงActivityResultContracts
เป็นวิธีใหม่ในการทำสิ่งต่าง ๆ นับจากนี้เป็นต้นไป
ฉันใช้เวลาหลายชั่วโมงกว่าจะได้งานนี้ รหัสมันเกือบจะเป็น copy-paste จากdeveloper.android.comซึ่งมีความแตกต่างเล็กน้อย
ขออนุญาตนี้ในAndroidManifest.xml
:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
ในของคุณActivity
เริ่มต้นด้วยการกำหนดสิ่งนี้:
static final int REQUEST_IMAGE_CAPTURE = 1;
private Bitmap mImageBitmap;
private String mCurrentPhotoPath;
private ImageView mImageView;
จากนั้นยิงสิ่งนี้Intent
ในonClick
:
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
Log.i(TAG, "IOException");
}
// Continue only if the File was successfully created
if (photoFile != null) {
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);
}
}
เพิ่มวิธีการสนับสนุนต่อไปนี้:
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, // prefix
".jpg", // suffix
storageDir // directory
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
จากนั้นรับผล:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
try {
mImageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(mCurrentPhotoPath));
mImageView.setImageBitmap(mImageBitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
อะไรที่ทำให้มันทำงานเป็นMediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(mCurrentPhotoPath))
ซึ่งจะแตกต่างจากรหัสจากdeveloper.android.com FileNotFoundException
รหัสต้นฉบับให้ฉัน
android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/JPEG_20180823_102340_722874009725833047.jpg exposed beyond app through ClipData.Item.getUri()
ฉันจะได้รับ ความคิดเกี่ยวกับวิธีการแก้ไขปัญหานี้? @AlbertVilaCalvo
storageDir = Context.getFilesDir();
storageDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES);
มิฉะนั้นฉันได้รับอนุญาตปฏิเสธข้อผิดพลาด
จับภาพ + เลือกจากคลังภาพ:
a = (ImageButton)findViewById(R.id.imageButton1);
a.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectImage();
}
});
}
private File savebitmap(Bitmap bmp) {
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
OutputStream outStream = null;
// String temp = null;
File file = new File(extStorageDirectory, "temp.png");
if (file.exists()) {
file.delete();
file = new File(extStorageDirectory, "temp.png");
}
try {
outStream = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return file;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void selectImage() {
final CharSequence[] options = { "Take Photo", "Choose from Gallery","Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Add Photo!");
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Take Photo"))
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
//pic = f;
startActivityForResult(intent, 1);
}
else if (options[item].equals("Choose from Gallery"))
{
Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 2);
}
else if (options[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == 1) {
//h=0;
File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
File photo = new File(Environment.getExternalStorageDirectory(), "temp.jpg");
//pic = photo;
break;
}
}
try {
Bitmap bitmap;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),
bitmapOptions);
a.setImageBitmap(bitmap);
String path = android.os.Environment
.getExternalStorageDirectory()
+ File.separator
+ "Phoenix" + File.separator + "default";
//p = path;
f.delete();
OutputStream outFile = null;
File file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
try {
outFile = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outFile);
//pic=file;
outFile.flush();
outFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
} else if (requestCode == 2) {
Uri selectedImage = data.getData();
// h=1;
//imgui = selectedImage;
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor c = getContentResolver().query(selectedImage,filePath, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath));
Log.w("path of image from gallery......******************.........", picturePath+"");
a.setImageBitmap(thumbnail);
}
}
ResultCode == 1
ข้างในResultCode == RESULT_OK
?
requestCode==1
จะช่วยให้แจ้งผู้ริเริ่มการร้องขอ
ฉันรู้ว่ามันเป็นเธรดที่ค่อนข้างเก่า แต่โซลูชันทั้งหมดเหล่านี้ยังไม่เสร็จสมบูรณ์และไม่ทำงานบนอุปกรณ์บางอย่างเมื่อผู้ใช้หมุนกล้องเพราะข้อมูลในแอคทีฟ ดังนั้นนี่คือทางออกที่ฉันได้ทดสอบกับอุปกรณ์จำนวนมากและยังไม่พบปัญหาใด ๆ
ก่อนอื่นให้ประกาศตัวแปร Uri ของคุณในกิจกรรมของคุณ:
private Uri uriFilePath;
จากนั้นสร้างโฟลเดอร์ชั่วคราวของคุณสำหรับจัดเก็บภาพที่ถ่ายและตั้งใจถ่ายภาพด้วยกล้อง:
PackageManager packageManager = getActivity().getPackageManager();
if (packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
File mainDirectory = new File(Environment.getExternalStorageDirectory(), "MyFolder/tmp");
if (!mainDirectory.exists())
mainDirectory.mkdirs();
Calendar calendar = Calendar.getInstance();
uriFilePath = Uri.fromFile(new File(mainDirectory, "IMG_" + calendar.getTimeInMillis()));
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uriFilePath);
startActivityForResult(intent, 1);
}
และตอนนี้ที่นี่เป็นหนึ่งในสิ่งที่สำคัญที่สุดคุณต้องบันทึก uriFilePath ของคุณใน onSaveInstanceState เพราะถ้าคุณไม่ทำเช่นนั้นและผู้ใช้หมุนอุปกรณ์ของเขาในขณะที่ใช้กล้อง uri ของคุณจะว่างเปล่า
@Override
protected void onSaveInstanceState(Bundle outState) {
if (uriFilePath != null)
outState.putString("uri_file_path", uriFilePath.toString());
super.onSaveInstanceState(outState);
}
หลังจากนั้นคุณควรกู้ uri ในวิธีการ onCreate ของคุณเสมอ:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
if (uriFilePath == null && savedInstanceState.getString("uri_file_path") != null) {
uriFilePath = Uri.parse(savedInstanceState.getString("uri_file_path"));
}
}
}
และนี่คือส่วนสุดท้ายในการรับ Uri ของคุณใน
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == 1) {
String filePath = uriFilePath.getPath(); // Here is path of your captured image, so you can create bitmap from it, etc.
}
}
}
ป.ล. อย่าลืมเพิ่มการอนุญาตสำหรับ Camera และ Ext พื้นที่เก็บข้อมูลที่เขียนถึง Manifest ของคุณ
ที่นี่คุณสามารถเปิดกล้องหรือคลังภาพและตั้งค่าภาพที่เลือกไว้เป็นมุมมองภาพ
private static final String IMAGE_DIRECTORY = "/YourDirectName";
private Context mContext;
private CircleImageView circleImageView; // imageview
private int GALLERY = 1, CAMERA = 2;
เพิ่มสิทธิ์ในรายการ
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="ANDROID.PERMISSION.READ_EXTERNAL_STORAGE" />
ใน onCreate ()
requestMultiplePermissions(); // check permission
circleImageView = findViewById(R.id.profile_image);
circleImageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showPictureDialog();
}
});
แสดงกล่องโต้ตอบตัวเลือก (เพื่อเลือกภาพจากกล้องหรือแกลเลอรี่)
private void showPictureDialog() {
AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
pictureDialog.setTitle("Select Action");
String[] pictureDialogItems = {"Select photo from gallery", "Capture photo from camera"};
pictureDialog.setItems(pictureDialogItems,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
choosePhotoFromGallary();
break;
case 1:
takePhotoFromCamera();
break;
}
}
});
pictureDialog.show();
}
รับภาพจากคลังภาพ
public void choosePhotoFromGallary() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, GALLERY);
}
รับภาพจากกล้อง
private void takePhotoFromCamera() {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA);
}
เมื่อเลือกหรือจับภาพแล้ว
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == this.RESULT_CANCELED) {
return;
}
if (requestCode == GALLERY) {
if (data != null) {
Uri contentURI = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI);
String path = saveImage(bitmap);
Toast.makeText(getApplicationContext(), "Image Saved!", Toast.LENGTH_SHORT).show();
circleImageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Failed!", Toast.LENGTH_SHORT).show();
}
}
} else if (requestCode == CAMERA) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
circleImageView.setImageBitmap(thumbnail);
saveImage(thumbnail);
Toast.makeText(getApplicationContext(), "Image Saved!", Toast.LENGTH_SHORT).show();
}
}
ตอนนี้ถึงเวลาเก็บภาพแล้ว
public String saveImage(Bitmap myBitmap) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File wallpaperDirectory = new File(Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
if (!wallpaperDirectory.exists()) { // have the object build the directory structure, if needed.
wallpaperDirectory.mkdirs();
}
try {
File f = new File(wallpaperDirectory, Calendar.getInstance().getTimeInMillis() + ".jpg");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
MediaScannerConnection.scanFile(this,
new String[]{f.getPath()},
new String[]{"image/jpeg"}, null);
fo.close();
Log.d("TAG", "File Saved::--->" + f.getAbsolutePath());
return f.getAbsolutePath();
} catch (IOException e1) {
e1.printStackTrace();
}
return "";
}
ขออนุญาต
private void requestMultiplePermissions() {
Dexter.withActivity(this)
.withPermissions(
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE)
.withListener(new MultiplePermissionsListener() {
@Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
if (report.areAllPermissionsGranted()) { // check if all permissions are granted
Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show();
}
if (report.isAnyPermissionPermanentlyDenied()) { // check for permanent denial of any permission
// show alert dialog navigating to Settings
//openSettingsDialog();
}
}
@Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
token.continuePermissionRequest();
}
}).
withErrorListener(new PermissionRequestErrorListener() {
@Override
public void onError(DexterError error) {
Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show();
}
})
.onSameThread()
.check();
}
นี่คือรหัสที่ฉันใช้ในการบันทึกและบันทึกภาพจากกล้องจากนั้นแสดงเป็นภาพ คุณสามารถใช้ตามความต้องการของคุณ
คุณต้องบันทึกภาพกล้องไปยังตำแหน่งเฉพาะจากนั้นดึงจากตำแหน่งนั้นแล้วแปลงเป็นไบต์อาร์เรย์
นี่คือวิธีในการเปิดกิจกรรมภาพกล้อง
private static final int CAMERA_PHOTO = 111;
private Uri imageToUploadUri;
private void captureCameraImage() {
Intent chooserIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(Environment.getExternalStorageDirectory(), "POST_IMAGE.jpg");
chooserIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
imageToUploadUri = Uri.fromFile(f);
startActivityForResult(chooserIntent, CAMERA_PHOTO);
}
วิธี onActivityResult () ของคุณควรเป็นเช่นนี้
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_PHOTO && resultCode == Activity.RESULT_OK) {
if(imageToUploadUri != null){
Uri selectedImage = imageToUploadUri;
getContentResolver().notifyChange(selectedImage, null);
Bitmap reducedSizeBitmap = getBitmap(imageToUploadUri.getPath());
if(reducedSizeBitmap != null){
ImgPhoto.setImageBitmap(reducedSizeBitmap);
Button uploadImageButton = (Button) findViewById(R.id.uploadUserImageButton);
uploadImageButton.setVisibility(View.VISIBLE);
}else{
Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show();
}
}else{
Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show();
}
}
}
นี่คือเมธอด getBitmap () ที่ใช้ใน onActivityResult () ฉันได้ทำการปรับปรุงประสิทธิภาพทั้งหมดที่สามารถทำได้ในขณะที่รับบิตแมปภาพจากกล้อง
private Bitmap getBitmap(String path) {
Uri uri = Uri.fromFile(new File(path));
InputStream in = null;
try {
final int IMAGE_MAX_SIZE = 1200000; // 1.2MP
in = getContentResolver().openInputStream(uri);
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, o);
in.close();
int scale = 1;
while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) >
IMAGE_MAX_SIZE) {
scale++;
}
Log.d("", "scale = " + scale + ", orig-width: " + o.outWidth + ", orig-height: " + o.outHeight);
Bitmap b = null;
in = getContentResolver().openInputStream(uri);
if (scale > 1) {
scale--;
// scale to max possible inSampleSize that still yields an image
// larger than target
o = new BitmapFactory.Options();
o.inSampleSize = scale;
b = BitmapFactory.decodeStream(in, null, o);
// resize to desired dimensions
int height = b.getHeight();
int width = b.getWidth();
Log.d("", "1th scale operation dimenions - width: " + width + ", height: " + height);
double y = Math.sqrt(IMAGE_MAX_SIZE
/ (((double) width) / height));
double x = (y / height) * width;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x,
(int) y, true);
b.recycle();
b = scaledBitmap;
System.gc();
} else {
b = BitmapFactory.decodeStream(in);
}
in.close();
Log.d("", "bitmap size - width: " + b.getWidth() + ", height: " +
b.getHeight());
return b;
} catch (IOException e) {
Log.e("", e.getMessage(), e);
return null;
}
}
หวังว่ามันจะช่วย!
จับภาพจากกล้อง + เลือกภาพจากแกลเลอรี่และตั้งเป็นพื้นหลังของเค้าโครงหรือมุมมองภาพ นี่คือตัวอย่างรหัส
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class Post_activity extends Activity
{
final int TAKE_PICTURE = 1;
final int ACTIVITY_SELECT_IMAGE = 2;
ImageView openCameraOrGalleryBtn,cancelBtn;
LinearLayout backGroundImageLinearLayout;
public void onCreate(Bundle savedBundleInstance) {
super.onCreate(savedBundleInstance);
overridePendingTransition(R.anim.slide_up,0);
setContentView(R.layout.post_activity);
backGroundImageLinearLayout=(LinearLayout)findViewById(R.id.background_image_linear_layout);
cancelBtn=(ImageView)findViewById(R.id.cancel_icon);
openCameraOrGalleryBtn=(ImageView)findViewById(R.id.camera_icon);
openCameraOrGalleryBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
selectImage();
}
});
cancelBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
overridePendingTransition(R.anim.slide_down,0);
finish();
}
});
}
public void selectImage()
{
final CharSequence[] options = { "Take Photo", "Choose from Gallery","Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(Post_activity.this);
builder.setTitle("Add Photo!");
builder.setItems(options,new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
if(options[which].equals("Take Photo"))
{
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, TAKE_PICTURE);
}
else if(options[which].equals("Choose from Gallery"))
{
Intent intent=new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, ACTIVITY_SELECT_IMAGE);
}
else if(options[which].equals("Cancel"))
{
dialog.dismiss();
}
}
});
builder.show();
}
public void onActivityResult(int requestcode,int resultcode,Intent intent)
{
super.onActivityResult(requestcode, resultcode, intent);
if(resultcode==RESULT_OK)
{
if(requestcode==TAKE_PICTURE)
{
Bitmap photo = (Bitmap)intent.getExtras().get("data");
Drawable drawable=new BitmapDrawable(photo);
backGroundImageLinearLayout.setBackgroundDrawable(drawable);
}
else if(requestcode==ACTIVITY_SELECT_IMAGE)
{
Uri selectedImage = intent.getData();
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor c = getContentResolver().query(selectedImage,filePath, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath));
Drawable drawable=new BitmapDrawable(thumbnail);
backGroundImageLinearLayout.setBackgroundDrawable(drawable);
}
}
}
public void onBackPressed() {
super.onBackPressed();
//overridePendingTransition(R.anim.slide_down,0);
}
}
Add these permission in Androidmenifest.xml file
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
ในกิจกรรม:
@Override
protected void onCreate(Bundle savedInstanceState) {
image = (ImageView) findViewById(R.id.imageButton);
image.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
SimpleDateFormat sdfPic = new SimpleDateFormat(DATE_FORMAT);
currentDateandTime = sdfPic.format(new Date()).replace(" ", "");
File imagesFolder = new File(IMAGE_PATH, currentDateandTime);
imagesFolder.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = IMAGE_NAME + n + IMAGE_FORMAT;
File file = new File(imagesFolder, fname);
outputFileUri = Uri.fromFile(file);
cameraIntent= new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, CAMERA_DATA);
}catch(Exception e) {
e.printStackTrace();
}
}
});
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case CAMERA_DATA :
final int IMAGE_MAX_SIZE = 300;
try {
// Bitmap bitmap;
File file = null;
FileInputStream fis;
BitmapFactory.Options opts;
int resizeScale;
Bitmap bmp;
file = new File(outputFileUri.getPath());
// This bit determines only the width/height of the
// bitmap
// without loading the contents
opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
fis = new FileInputStream(file);
BitmapFactory.decodeStream(fis, null, opts);
fis.close();
// Find the correct scale value. It should be a power of
// 2
resizeScale = 1;
if (opts.outHeight > IMAGE_MAX_SIZE
|| opts.outWidth > IMAGE_MAX_SIZE) {
resizeScale = (int) Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE/ (double) Math.max(opts.outHeight, opts.outWidth)) / Math.log(0.5)));
}
// Load pre-scaled bitmap
opts = new BitmapFactory.Options();
opts.inSampleSize = resizeScale;
fis = new FileInputStream(file);
bmp = BitmapFactory.decodeStream(fis, null, opts);
Bitmap getBitmapSize = BitmapFactory.decodeResource(
getResources(), R.drawable.male);
image.setLayoutParams(new RelativeLayout.LayoutParams(
200,200));//(width,height);
image.setImageBitmap(bmp);
image.setRotation(90);
fis.close();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 70, baos);
imageByte = baos.toByteArray();
break;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ใน layout.xml:
enter code here
<RelativeLayout
android:id="@+id/relativeLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/XXXXXXX"
android:textAppearance="?android:attr/textAppearanceSmall" />
ใน manifest.xml:
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" />
ฉันสร้างกล่องโต้ตอบพร้อมตัวเลือกเพื่อเลือกภาพจากแกลเลอรี่หรือกล้อง ด้วยการโทรกลับเป็น
ตอนแรกเราต้องกำหนดสิทธิ์ใน AndroidManifest ตามที่เราต้องเขียนร้านค้าภายนอกในขณะที่สร้างไฟล์และอ่านภาพจากแกลเลอรี่
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
สร้าง file_paths xml ในแอพ / src / main / res / xml / file_paths.xml
ด้วยเส้นทาง
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
จากนั้นเราจำเป็นต้องกำหนดตัวกำหนดไฟล์เพื่อสร้าง Content uri เพื่อเข้าถึงไฟล์ที่เก็บไว้ในที่จัดเก็บข้อมูลภายนอก
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
เค้าโครง Dailog
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.50" />
<ImageView
android:id="@+id/gallery"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline2"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_menu_gallery" />
<ImageView
android:id="@+id/camera"
android:layout_width="48dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_menu_camera" />
</androidx.constraintlayout.widget.ConstraintLayout>
ImagePicker Dailog
public class ImagePicker extends BottomSheetDialogFragment {
ImagePicker.GetImage getImage;
publ` enter code here` ic ImagePicker(ImagePicker.GetImage getImage, boolean allowMultiple) {
this.getImage = getImage;
}
File cameraImage;@
Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bottom_sheet_imagepicker, container, false);
view.findViewById(R.id.camera).setOnClickListener(new View.OnClickListener() {@
Override
public void onClick(View view) {
if(ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE
}, 2000);
} else {
captureFromCamera();
}
}
});
view.findViewById(R.id.gallery).setOnClickListener(new View.OnClickListener() {@
Override
public void onClick(View view) {
if(ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE
}, 2000);
} else {
startGallery();
}
}
});
return view;
}
public interface GetImage {
void setGalleryImage(Uri imageUri);
void setCameraImage(String filePath);
void setImageFile(File file);
}@
Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == Activity.RESULT_OK) {
if(requestCode == 1000) {
Uri returnUri = data.getData();
getImage.setGalleryImage(returnUri);
Bitmap bitmapImage = null;
}
if(requestCode == 1002) {
if(cameraImage != null) {
getImage.setImageFile(cameraImage);
}
getImage.setCameraImage(cameraFilePath);
}
}
}
private void startGallery() {
Intent cameraIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
cameraIntent.setType("image/*");
if(cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(cameraIntent, 1000);
}
}
private String cameraFilePath;
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "Camera");
File image = File.createTempFile(imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ );
cameraFilePath = "file://" + image.getAbsolutePath();
cameraImage = image;
return image;
}
private void captureFromCamera() {
try {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID + ".provider", createImageFile()));
startActivityForResult(intent, 1002);
} catch(IOException ex) {
ex.printStackTrace();
}
}
}
โทรในกิจกรรมหรือชิ้นส่วนเช่นนี้กำหนด ImagePicker ในส่วน / กิจกรรม
ImagePicker imagePicker;
จากนั้นเรียกใช้ dailog เมื่อคลิกปุ่ม
imagePicker = new ImagePicker(new ImagePicker.GetImage() {
@Override
public void setGalleryImage(Uri imageUri) {
Log.i("ImageURI", imageUri + "");
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContext().getContentResolver().query(imageUri, filePathColumn, null, null, null);
assert cursor != null;
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
mediaPath = cursor.getString(columnIndex);
// Set the Image in ImageView for Previewing the Media
imagePreview.setImageBitmap(BitmapFactory.decodeFile(mediaPath));
cursor.close();
}
@Override
public void setCameraImage(String filePath) {
mediaPath =filePath;
Glide.with(getContext()).load(filePath).into(imagePreview);
}
@Override
public void setImageFile(File file) {
cameraImage = file;
}
}, true);
imagePicker.show(getActivity().getSupportFragmentManager(), imagePicker.getTag());
นี่คือรหัสที่สมบูรณ์:
package com.example.cameraa;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity {
Button btnTackPic;
Uri photoPath;
ImageView ivThumbnailPhoto;
static int TAKE_PICTURE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get reference to views
btnTackPic = (Button) findViewById(R.id.bt1);
ivThumbnailPhoto = (ImageView) findViewById(R.id.imageView1);
btnTackPic.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, TAKE_PICTURE);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == TAKE_PICTURE && resultCode == RESULT_OK) {
Bitmap photo = (Bitmap)intent.getExtras().get("data");
ivThumbnailPhoto.setImageBitmap(photo);
ivThumbnailPhoto.setVisibility(View.VISIBLE);
}
}
}
อย่าลืมเพิ่มสิทธิ์สำหรับกล้องด้วย
คุณสามารถใช้รหัสนี้เพื่อฟัง onClick (คุณสามารถใช้ ImageView หรือปุ่ม)
image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, 1);
}
}
});
เพื่อแสดงใน imageView ของคุณ
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
bitmap = (Bitmap) extras.get("data");
image.setImageBitmap(bitmap);
}
}
หมายเหตุ: ใส่สิ่งนี้ลงในรายการ
<uses-feature android:name="android.hardware.camera" android:required="true" />
ใช้รหัสต่อไปนี้เพื่อจับภาพโดยใช้กล้องมือถือของคุณ หากคุณกำลังใช้แอนดรอยด์ที่มีเวอร์ชันสูงกว่า Lolipop คุณควรเพิ่มคำขออนุญาตด้วย
private void cameraIntent()
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CAMERA);
}
@override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(photo);
}
}
Bitmap photo = (Bitmap) data.getExtras().get("data");
รับภาพขนาดย่อจากกล้อง มีบทความเกี่ยวกับวิธีจัดเก็บรูปภาพในที่จัดเก็บข้อมูลภายนอกจากกล้อง
ลิงค์ที่มีประโยชน์
โปรดทำตามตัวอย่างนี้ด้วยการใช้งานนี้โดยใช้การสนับสนุน Kotlin และ Andoirdx:
button1.setOnClickListener{
file = getPhotoFile()
val uri: Uri = FileProvider.getUriForFile(applicationContext, "com.example.foto_2.filrprovider", file!!)
captureImage.putExtra(MediaStore.EXTRA_OUTPUT, uri)
val camaraActivities: List<ResolveInfo> = applicationContext.getPackageManager().queryIntentActivities(captureImage, PackageManager.MATCH_DEFAULT_ONLY)
for (activity in camaraActivities) {
applicationContext.grantUriPermission(activity.activityInfo.packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
startActivityForResult(captureImage, REQUEST_PHOTO)
}
และผลกิจกรรม:
if (requestCode == REQUEST_PHOTO) {
val uri = FileProvider.getUriForFile(applicationContext, "com.example.foto_2.filrprovider", file!!)
applicationContext.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
imageView1.viewTreeObserver.addOnGlobalLayoutListener {
width = imageView1.width
height = imageView1.height
imageView1.setImageBitmap(getScaleBitmap(file!!.path , width , height))
}
if(width!=0&&height!=0){
imageView1.setImageBitmap(getScaleBitmap(file!!.path , width , height))
}else{
val size = Point()
this.windowManager.defaultDisplay.getSize(size)
imageView1.setImageBitmap(getScaleBitmap(file!!.path , size.x , size.y))
}
}
คุณสามารถรับรายละเอียดเพิ่มเติมได้ที่https://github.com/joelmmx/take_photo_kotlin.git
ฉันหวังว่ามันจะช่วยคุณ!