In my app i need to pick image from gallery to my ImageView. If I pick simple image, for example, downloaded from the Internet, it works fine. But if i pick photo made on my phone i get W/OpenGLRenderer: Bitmap too large to be uploaded into a texture (4160x3120, max=4096x4096)
Using Glide to load the photo gives this
Caused by: java.lang.IllegalArgumentException: Unknown type class android.graphics.Bitmap. You must provide a Model of a type for which there is a registered ModelLoader, if you are using a custom model, you must first call Glide#register with a ModelLoaderFactory for your custom model class
This is my code which picks up an image and creates a bitmap out of it.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// When an Image is picked
if (requestCode == SELECT_PHOTO && resultCode == RESULT_OK
&& null != data) {
Uri imageUri = data.getData();
InputStream inputStream;
try {
inputStream = getContentResolver().openInputStream(imageUri);
Bitmap image = BitmapFactory.decodeStream(inputStream);
commentImage = (ImageView) findViewById(R.id.comment_image);
//Glide.with(this).load(image).asBitmap().override(4095, 4095).into(commentImage);
commentImage.setImageBitmap(image);
//commentImage.setImageBitmap(Bitmap.createScaledBitmap(image, 4095, 2048, false));
Toast.makeText(this, "SUCCESS", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
// show a message to the user indictating that the image is unavailable.
Toast.makeText(this, "Unable to open image", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(this, "You haven't picked Image",
Toast.LENGTH_LONG).show();
}
}
How can I scale an Image in case if it is too big?
You can use the following to compress the bitmap, here bitmapImage is your bitmap object. :
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmapImage.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream); //90 refers to 90% quality, or 10% compression
byte[] data = byteArrayOutputStream.toByteArray();
Bitmap compressedBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Related
I am currently working on an activity that will let the user select an image from the gallery, and then put that image's URI into an SQLite database.
I have another activity where I take that URI and display it on an ImageView. I have this working perfectly on Lollipop and older. But anything newer it crashes when I pull up the activity that displays the image.
Here is the LOGCAT line of the crash:
Caused by: java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.contentprovider.MediaContentProvider from ProcessRecord{8193e94 13574:jeremy.com.wineofmine/u0a97} (pid=13574, uid=10097) that is not exported from uid 10044
This makes it seem like a permissions thing, but I am requesting the WRITE_EXTERNAL_STORAGE and READ_EXTERNAL STORAGE in the manifest, as well as requesting those permissions on run-time on the activity where it displays the image.
And here is the exact line where it's crashing (this is in the activity where it displays the image:)
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageURI);
And this is imageURI:
imageURI = Uri.parse(cursor.getString(cursor.getColumnIndexOrThrow(WineContract.WineEntry.COLUMN_WINE_IMAGE)));
//This code returns this: content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F62/ACTUAL/860591124
Here is the code to the relevant bits.
This is the intent to open up the gallery:
Intent intentGallery = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intentGallery, SELECT_IMAGE);
And this is the onActivityResult method. The main goal of this method is to set the imageThumbail ImageView as the thumbnail, and also to set "photoURI" as the selected image's URI.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//This is if they choose an image from the gallery
if (requestCode == SELECT_IMAGE && resultCode == RESULT_OK) {
if (requestCode == SELECT_IMAGE) {
// Get the url from data
Uri selectedImageUri = data.getData();
if (null != selectedImageUri) {
// Get the path from the Uri
String path = getPathFromURI(selectedImageUri);
Log.i("ADDACTIVITY", "Image Path : " + path);
bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);
} catch (IOException e) {
e.printStackTrace();
}
bitmapThumbnail = ThumbnailUtils.extractThumbnail(bitmap,175,175);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmapThumbnail.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byteArray = stream.toByteArray();
// Set the image in ImageView
imageThumbnail.setImageBitmap(bitmapThumbnail);
//Setting photoURI (which gets put into the database) as the gallery's image URI
photoURI = data.getData();
}
}
}
}
Any pointers to what I could be doing wrong, would be great.
I do not know , is the problem the cut function or the Decoding Code ? :
I use the code for for uploading:
public void Upload(View view) {
Bitmap Bimg = ((BitmapDrawable) image1.getDrawable()).getBitmap();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Bimg.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
// Bimg.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream); // bad too
encodimg = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);
and i use this code to cut the image :
private void performCrop(){
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(picUri, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("outputX", 512);
cropIntent.putExtra("outputY", 512);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, PIC_CROP);
Toast toast = Toast.makeText(this, "Done", Toast.LENGTH_SHORT);
}
catch(ActivityNotFoundException anfe){
String errorMessage = "Soory - your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
remark : I use a small image in xml as small preview :
<ImageView
android:onClick="Load_Picture"
android:id="#+id/imageview1"
android:background="#drawable/default_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
but i do not thing, the image size in xml is the problem
Iget the Bitmap from Camera or From Galerie like that :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ( requestCode==111 && resultCode==RESULT_OK ){
// Uri uri = data.getData();
// imageView.setImageURI(uri);
imageView.setImageBitmap((Bitmap)data.getExtras().get("data"));
}
}
the Problem is the cut methode , because if i upload the bitmap before cutting, i get very good quality. so the Problem is :
performCrop(){
You are not trying to send your cropped image to a server.
Instead you display the cropped image in an imageview. Then after that you take an screendump from that imageview and upload that to the server. Of course hat screendump has bad quality.
Instead you should upload the image you get from the crop function.
Please compare the resolution in pixels of all involved images.
I'm using BluetoothSPP Android Library. I have problems for send and receive data byte[]
User 1 takes a photo from camera, get it and send to other user.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
Bitmap bitmap = (Bitmap) bundle.get("data");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
byte[] bitmapByte = outputStream.toByteArray();
bluetoothSPP.send(bitmapByte, true); **//Send the Bitmap array**
}
}
User 2 receive the Bitmap byte[].
bluetoothspp.setOnDataReceivedListener(new BluetoothSPP.OnDataReceivedListener() {
public void onDataReceived(byte[] data, String message) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Glide.with(ChatActivity.this).load(bitmap ).asBitmap().into(imgFundo); //Use Glide for show Bitmap
}
});
But I always get an error and Glide can not display the image.
I did a debug and the data comes in several parts, like an array of bytes.
- How can I build a Bitmap from data received?
Thanks
After following part of this tutorial and the second answer of this question in SO, I managed to save a photo that I chose from my gallery to my object in Parse.
The problem is that the photo that I saved has .PNG extension (it was just a screenshot).
When I tried to choose a normal photo from the camera folder, nothing was saved and an exception was occurred.
The extension of ALL the other photos is .jpg NOT .jpeg.
Because of that, i tried to put if statements, so that I can check the type of the photo.
The result of the code that is following is that when I choose a .JPG photo, the data type is NULL.
But, how can I manage to save the .jpg photos in my Parse Object ?
In my Activity I have 2 buttons. when you press the first one ( sign_in ), there is the listener that does correctly all the checks of the other data in my page and then if all data are okay, it calls a function ( postData() ), in which there will be done the saving to parse via objects.
The second button is about adding a photo from gallery. In my .java activity, I have this exact listener:
picture.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI), GET_FROM_GALLERY);
}
});
This is the function that it is being called from the onClick function of the button:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//Detects request codes
if(requestCode==GET_FROM_GALLERY && resultCode == Activity.RESULT_OK) {
Uri selectedImage = data.getData();
selectedImageType =data.getType();
Toast.makeText(SignUpActivity.this, "Type: "+selectedImageType,
Toast.LENGTH_SHORT).show();
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
// Convert it to byte
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// Compress image to lower quality scale 1 - 100
if (selectedImageType == "JPEG"){
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
// bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
image = stream.toByteArray();
}
else if (selectedImageType == "JPG" || selectedImageType == "jpg"){
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
// bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
image = stream.toByteArray();
}
else if (selectedImageType == "PNG") {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
// bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
image = stream.toByteArray();
}
else{
Toast.makeText(SignUpActivity.this, "Please pick a JPEG or PNG photo!",
Toast.LENGTH_SHORT).show();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And this is the function that saves the data:
public void postData(final String username,final String password,final String email,final String gender,final String age) {
ParseObject user = new ParseObject("users");
user.put("username", username);
user.put("password", password);
user.put("email", email);
user.put("gender", gender);
user.put("age_category", age);
user.put("admin", false);
ParseFile file = null;
if (selectedImageType == "JPEG"){
file = new ParseFile("profile_picture.jpeg", image);
}
else if (selectedImageType == "JPG" || selectedImageType == "jpg"){
file = new ParseFile("profile_picture.jpg", image);
}
else if (selectedImageType == "PNG"){
file = new ParseFile("profile_picture.png", image);
}
else{
// Show a simple toast message
Toast.makeText(SignUpActivity.this, "Please pick a JPEG or PNG photo!",
Toast.LENGTH_SHORT).show();
}
// Upload the image into Parse Cloud
file.saveInBackground();
user.put("photo", file);
// Create the class and the columns
user.saveInBackground();
// Show a simple toast message
Toast.makeText(SignUpActivity.this, "Image Uploaded",
Toast.LENGTH_SHORT).show();
Intent intent = new Intent(SignUpActivity.this, LoginActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.push_down_in, R.anim.push_down_out);
//finish();
}
remove your if statements that try to keep track of the "selectedImageType" throughout the process of bitmap creation and image Post to parse.com.
Once you have a bitmap, you can simply specify all compression to "Bitmap.CompressFormat.JPEG" and then simply post all jpgs to parse.com.
So .jpeg works and .jpg doesn't? How about this then (notice you shouldn't compare strings with ==):
if (selectedImageType.toUpperCase().equals("JPEG") || selectedImageType.toUpperCase().equals("JPG")){
file = new ParseFile("profile_picture.jpeg", image);
}
Also you can consolidate some earlier code:
if (selectedImageType.toUpperCase().equals("JPEG") || selectedImageType.toUpperCase().equals("JPG")){
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
image = stream.toByteArray();
}
I take a picture in Android via
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, CAMERA_REQUEST);
and show / save it via
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
ImageView theImage = (ImageView) findViewById(R.id.preview);
theImage.setImageBitmap(photo);
// try to save its
try {
File testFile = new File(Environment.getExternalStorageDirectory(), "test.png");
testFile.createNewFile();
FileOutputStream out = new FileOutputStream(testFile);
photo.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
This works fine, however the quality of the image is very bad. I do not know why, since I take the picture with 8 mega pixels.
Is there a way to do this without requiring the camera manually?
Take a closer look at this post: there are two ways to capture an image in Android. First one is designed for taking small and lightweight pictures - that's the approach you use, and the second one captures full-sized pictures and writes them to storage. The post describes both ways of accomplishing this task.