resizing images in gallery for image processing app. android - android

i've an image processing app. If i take a picture using the part of the app that captures the image, the image is eventually displayed corectly on the screen. This is because i have specified camera params using the hardwares screen size. if i try to load an image that was taken from the phone's camera (not the app's camera), then the image is too large on the screen and sometimes too large from a byte point of view. how can i resize or compress the images in the gallery so that my app can use them? thanks
public class DisplayUndistortedBitmapFromGalleryActivity extends Activity {
private static final String TAG = "*********DUBFGActivity";
private Context mContext = this;
Uri uri;
private Bitmap mbitmap = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
uri = getIntent().getData();
if(uri != null){
Log.e(TAG, "uri ok");
}else {
Log.e(TAG, "uri not ok");
}
try {
mbitmap = Media.getBitmap(getContentResolver(), uri);
//setMbitmap(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(mbitmap == null){
Log.e(TAG,"mbitmap is null");
}else{
Log.e(TAG,"mbitmap is not null");
}
.
public class DisplayUndistortedBitmapFromGallery extends View{
public DisplayUndistortedBitmapFromGallery(Context context) {
super(context);
}
public DisplayUndistortedBitmapFromGallery(Context context, AttributeSet attr) {
super(context,attr);
Log.e(TAG, "++++++++++ inside dubfgview constructor");
Bitmap bm = ((DisplayUndistortedBitmapFromGalleryActivity)getContext()).getMbitmap();
if(bm == null){
Log.e(TAG, "bm = null");
}else{
Log.e(TAG, "bm = not null");
}
bgr = bm.copy(bm.getConfig(), true);

If I understand your question correctly there are two problems. The first is that the ImageView isn't scaling the image to fit the screen and the second is that the Bitmaps are requiring too much RAM.
To solve the first problem simply tell the image view how you want the image to be scaled. Simply do the following:
imgView.setScaleType(ImageView.ScaleType.INSERT_SCALE_TYPE);
Here is a list of the different scale types.
If this doesn't solve the problem make sure the bounds of your ImageView aren't too large. Try hardcoding the size of the ImageView to something specific and see if that fixes the problem.
The second problem is really easy to fix. You simply need to tell BitmapFactory to downsample the image when its loaded. Here is an example:
int inSample = 4; // specifies how many 1/N samples to keep, in this case 1/4 off all samples are kept
opts = new BitmapFactory.Options();
opts.inSampleSize = inSample;
Bitmap b = BitmapFactory.decodeResource(c.getResources(), imgResId, opts);
For a more longer explanation see my answer to this question: Android GalleryView Recycling

Related

How to take the screen-shot of the current video frame in the videoView android?

I am using the video-view to play media and I want to take the screen shot of the current frame. I found some solutions which include using mediaMetaDataRetriever but that method is way too slow and does not perform well in many cases.
I can not use media player over texture view to capture view I knew that approach, because I need by default media controls in my app.
Is there any way to make that process fast?
My CODE:
public Bitmap getBitmapVideoView(){
MediaMetadataRetriever mediaMetadataRetriever;
mediaMetadataRetriever = new MediaMetadataRetriever();
try {
int currentPosition =videoView.getCurrentPosition();
mediaMetadataRetriever.setDataSource(getVideoURL(),new HashMap<String, String>());
Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(currentPosition*1000);
if (bitmap != null) {
// Canvas canvas = new Canvas(bitmap);
// textureview.draw(canvas);
return bitmap;
}
else{
return null;
}
}
catch (Exception e){
Log.i("Errorrr",e.getMessage());
return null;
}
finally {
try {
mediaMetadataRetriever.release();
}
catch (Exception e){
e.printStackTrace();
}
}
}
Approach:
Bitmap bitmap = Screenshot.INSTANCE.with((MainActivity)activity).setView(findViewById(R.id.relative)).setQuality(Quality.HIGH).getScreenshot();
LayoutInflater inflater = getLayoutInflater();
Toast toastShot = null;
View layout = inflater.inflate(R.layout.layout, (ViewGroup) findViewById(R.id.screen));
ImageView image = (ImageView) layout.findViewById(R.id.shot_image);
image.setImageBitmap(bitmap);
toastShot = new Toast(getApplicationContext());
toastShot.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toastShot.setDuration(Toast.LENGTH_LONG);
toastShot.setView(layout);
toastShot.show();
For taking screenshot you can use this library
implementation 'com.github.MindorksOpenSource:screenshot:v0.0.1'
And for taking screenshot just call this function on button click or any other event
var b = Screenshot.with(activity!!).setView(rl_imageText).setQuality(Quality.HIGH).getScreenshot()
Note: rl_imageText = This is the id of my xml relative layout of which i am taking screenshot.
It will provide you the bitmap of the screenshot and for saving it into the storage or getting path use the below mentioned function
private fun getImageUriFromBitmap(context: Context, bitmap: Bitmap): Uri {
val bytes = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes)
val path = MediaStore.Images.Media.insertImage(context.contentResolver, bitmap,"Title",null)
return Uri.parse(path.toString())
}
Note: Please mention if it will not work so that i will provide you other solution.

OutOfMemoryError with emodo/cropper library when using getCroppedImage

I am using edmodo/cropper library to crop the image after the user has taken the image from camera.
Link: https://github.com/edmodo/cropper/wiki
I got this issue on device GT-N7000 and some other android phones.
java.lang.OutOfMemoryError
1 at android.graphics.Bitmap.nativeCreate(Native Method)
2 at android.graphics.Bitmap.createBitmap(Bitmap.java:669)
3 at android.graphics.Bitmap.createBitmap(Bitmap.java:604)
4 at android.graphics.Bitmap.createBitmap(Bitmap.java:530)
5 at com.edmodo.cropper.CropImageView.getCroppedImage(CropImageView.java:357)
Does anyone know how to solve this issue. Please help me ,the device keep getting crashes.
I solved it by subsampling the captured image before storing it in cropView using BitmapFactory.Options.
Here is the code:
// setting path to the clicked image and cropped image
path_click = "sdcard/Pictures/Candice/Clicked.jpg";
path_crop = "sdcard/Pictures/Candice/Cropped.jpg";
final BitmapFactory.Options options = new BitmapFactory.Options();
//If set to a value > 1,requests the decoder to subsample the
//original image, returning a smaller image to save memory.
options.inSampleSize = 2;
clickedImage = BitmapFactory.decodeFile(path_click, options);
cropImageView.setImageBitmap(clickedImage);
// Sets initial aspect ratio to 10/10, for demonstration purposes
cropImageView.setAspectRatio(DEFAULT_ASPECT_RATIO_VALUES,
DEFAULT_ASPECT_RATIO_VALUES);
cropButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Here we save the cropped image and then call the next
// activity
// To retrieve the image contained within the Cropper window,
// use the provided method, getCroppedImage() to retrieve a
// Bitmap of the cropped image.
croppedImageBitmap = cropImageView.getCroppedImage();
/** Save cropped image to SD card using output streams **/
// An output stream that writes bytes to a file.
// If it does not exist, a new file will be created.
FileOutputStream out = null;
try {
out = new FileOutputStream(path_crop);
// Writing a compressed version of bitmap to outputstream.
croppedImageBitmap.compress(Bitmap.CompressFormat.JPEG, 90,
out);
// Just after compression,add
croppedImageBitmap.recycle();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
startActivity(chooseIntent);
}
});
I don't know how big is your image, but have you tried adding android:largeHeap="true" to your <application> tag in the AndroidManifest.xml?

How do I tell BitmapFactory.decodeStream to give me a full quality image?

So I have the following code in an AsyncTask. The AsyncTask takes in a url to an image file, downloads it into a Bitmap, saves the Bitmap off to disk somewhere, and then displays the Bitmap in an existing ImageView.
Here's the implementation of the doInBackground() call for my AsyncTask:
protected Bitmap doInBackground(String... urls) {
try {
URL image_url = new URL(urls[0]);
String image_url_prefix_regex = "http://www\\.somewebsite\\.com";
if (externalStorageIsAvailable()) {
String file_path = getExternalFilesDir(null).getPath() + image_url.toString().replaceAll(image_url_prefix_regex, "");
File target_file = new File(file_path);
if (!target_file.getParentFile().exists()) {
target_file.getParentFile().mkdirs();
}
BitmapFactory.Options bitmap_options = new BitmapFactory.Options();
bitmap_options.inScaled = false;
bitmap_options.inDither = false;
bitmap_options.inPreferredConfig = Bitmap.Config.ARGB_8888;
bitmap_options.inPreferQualityOverSpeed = true;
bitmap_options.inSampleSize = 1;
Bitmap image = BitmapFactory.decodeStream(image_url.openStream(), null, bitmap_options);
image.compress(CompressFormat.JPEG, 100, new FileOutputStream(target_file));
return image;
}
}
catch (MalformedURLException e) {
Log.v(DEBUG_TAG, "Error: Caught MalformedURLException");
}
catch (IOException e) {
Log.v(DEBUG_TAG, "Error: Caught IOException");
}
return null;
}
Then later in the onPostExecute() call I have this:
protected void onPostExecute(Bitmap image) {
ImageView mImageView = (ImageView) findViewById(R.id.main_image);
mImageView.setImageBitmap(image);
}
Yet when the code downloads and displays the image, the image is reduced in size and quality. How do I make it so that the resulting image is full quality? Those BitmapFactory.Options settings are the things I've tried thus far, but they did not seem to work.
Note that I'm not asking about the image that gets saved to external storage. I think that one will likely be of lower quality due to getting compressed again, but that shouldn't affect the image I'm sending to my ImageView, which is what I'm asking about. Of course, if there's anything wrong with these assumptions please point them out.
Why you are using Bitmap factory options while decoding bitmap Stream ?
Just use the
Bitmap image = BitmapFactory.decodeStream(image_url.openStream());
instead of
Bitmap image = BitmapFactory.decodeStream(image_url.openStream(), null, bitmap_options);

Android ImageButton setImageBitmap goes on the wrong element

I have a situation with three image buttons:
Take a photo by the camera
Delete the photo
Show a cropped2fit version of the image taken
I'm using the camera of the phone.
My problem is that SOMETIMES, apparently without no explanation, when I set the photo with setImageBitmap, it goes on the wrong imageButton (seems to be always the delete button, but I'm not really sure). Rebooting the device seems to solve the problem.
The code is as simple as it should be: I use findViewById casting the object into an ImageButton and setting the image with setImageBitmap.
ImageView iv = ((ImageView) findViewById(R.id.imgFotoPrima));
iv.setImageBitmap(fn.setupImage(data, PrimaOutputFileUri));
iv.setScaleType(ScaleType.CENTER_CROP);
public static Bitmap setupImage(Intent data, Uri outputFileUri) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2; // SAMPLE_SIZE = 2
Bitmap tempBitmap = null;
Bitmap bm = null;
try {
tempBitmap = (Bitmap) data.getExtras().get("data");
bm = tempBitmap;
Log.v("ManageImage-hero", "the data.getData seems to be valid");
FileOutputStream out = new FileOutputStream(outputFileUri.getPath());
tempBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
}
catch (NullPointerException ex) {
Log.v("ManageImage-other", "another phone type");
bm = otherImageProcessing(options, outputFileUri);
}
catch (Exception e) {
Log.e("ManageImage-setupImage", "problem setting up the image", e);
}
return bm;
}
The elements in the xml have different id.
I've tried the application on a Lenovo (7') and a Galaxy Tab 7 II.
It seems to happen only on the Galaxy Tab.
Could it be a problem on the tablet?? Anyone in my situation?

creating a drawable from sd card to set as a background in android

I am trying to use an image from the sd card and set it as the background for a relativelayout. I have tried other solutions that i have found here and elsewhere but they havent seemed to work for me. here is my code. I have commented out other ways that i have tried and didnt work. the only thing that worked for me was using setBackgroudnResource and using a resource from the app, but this was just to test to make sure mRoot was set up correctly. when I have tried all the other ways, it just doesn't set anything. Anyone know what I am doing wrong, or if there is a better way to do this?
//one way i tired...
//String extDir = Environment.getExternalStorageDirectory().toString();
//Drawable d = Drawable.createFromPath(extDir + "/pic.png");
//mRoot.setBackgroundDrawable(d);
//another way tried..
//Drawable d = Drawable.createFromPath("/sdcard/pic.png");
//mRoot.setBackgroundDrawable(d);
//last way i tried...
mRoot.setBackgroundDrawable(Drawable.createFromPath(new File(Environment.getExternalStorageDirectory(), "pic.png").getAbsolutePath()));
//worked, only to verify mRoot was setup correctly and it could be changed
//mRoot.setBackgroundResource(R.drawable.bkg);
You do not load a drawable from SD card but a bitmap. Here is a method to load it with the reduced sampling (quality) so the program will not complain if the image is too large. Then I guess you need to process this bitmap i.e. crop it and resize for the background.
// Read bitmap from Uri
public Bitmap readBitmap(Uri selectedImage) {
Bitmap bm = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2; //reduce quality
AssetFileDescriptor fileDescriptor =null;
try {
fileDescriptor = this.getContentResolver().openAssetFileDescriptor(selectedImage,"r");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
finally{
try {
bm = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
fileDescriptor.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return bm;
}
The Uri here can be supplied from a gallery picker activity.
The image then can be saved into application resources and loaded into an imageView
private void saveBackground(Bitmap Background) {
String strBackgroundFilename = "background_custom.jpg";
try {
Background.compress(CompressFormat.JPEG, 80, openFileOutput(strBackgroundFilename, MODE_PRIVATE));
} catch (Exception e) {
Log.e(DEBUG_TAG, "Background compression and save failed.", e);
}
Uri imageUriToSaveCameraImageTo = Uri.fromFile(new File(BackgroundSettings.this.getFilesDir(), strBackgroundFilename));
// Load this image
Bitmap bitmapImage = BitmapFactory.decodeFile(imageUriToSaveCameraImageTo.getPath());
Drawable bgrImage = new BitmapDrawable(bitmapImage);
//show it in a view
ImageView backgroundView = (ImageView) findViewById(R.id.BackgroundImageView);
backgroundView.setImageURI(null);
backgroundView.setImageDrawable(bgrImage);
}
File file = new File( url.getAbsolutePath(), imageUrl);
if (file.exists()) {
mDrawable = Drawable.createFromPath(file.getAbsolutePath());
}
I suggest checking that the drawable is being loaded correctly. Some things to try:
Try using a different image on the sd card
Put pic.png in R.drawable and make sure mRoot.setBackgroundResource() does what you expect
After loading the drawable, check d.getBounds() to make sure it is what you expect

Categories

Resources