How to fetch images from gallery and move in android application - android

I am working on Android Security app and I have to lock the images from gallery so I am trying to move images from gallery into my application.
I am using this code:
Cursor cursor = cursor1[0];
int i = 0;
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID));
long idC = Long.parseLong(id);
Uri newUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, idC);
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(cr,newUri);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100,stream );
Bitmap compBit = Bitmap.createScaledBitmap(bitmap, 100,100, true);
bitmap1[i] = compBit;
bitmap.recycle();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
but getting this exception:
Out of memory on a 4192360-byte allocation.

there is a training module on Displaying Bitmaps Efficiently - [link] http://developer.android.com/training/displaying-bitmaps/index.html .
It provide good information on handling out of memory exception with sample.

Related

Is there a way to rotate an Image without loading into Memory in Android?

Is there a way to read the orientation and rotate if needed?
I want the user to take a picture by the camera.
After that I check if the orientation is portrait. If not, rotate the Image and save it in internal storage for later use. (I have to store it in internal storage, for the case that the user deletes the image in gallery).
So here is my way to rotate the image:
int orientation = 0;
try {
ExifInterface exif = new ExifInterface(mCurrentPhotoPath);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);
} catch (IOException e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
Bitmap decodeFile = BitmapFactory.decodeFile(mCurrentPhotoPath);
Bitmap rotatedBitmap = Bitmap.createBitmap(decodeFile,0,0,decodeFile.getWidth(),decodeFile.getHeight(),matrix,true);
FileOutputStream out = null;
File pictureDir = new File(getFilesDir() + "/images/");
randomUUID = UUID.randomUUID().toString();
File file = new File(pictureDir.getAbsolutePath(), randomUUID + ".jpg");
try {
imagePath = file.getAbsolutePath();
out = new FileOutputStream(file);
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG,100,out);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
At line Bitmap decodeFile = BitmapFactory.decodeFile(mCurrentPhotoPath), I get on old devices an OOM.
I tried to use BitmapFactory.Options and inJustDecodeBounds=true but the rotatedImage is null.
So how to just read the orientation and rotate the image while saving it in internal storage?
I've read many posts in stackoverflow but none of them had the same case.
Is it possible without loading it in memory?
Thank you for any help!
Kind Regards,
raymondis

why screenshots have low quality?

I'm taking screenshot of my Layout with this code:
View u = findViewById(R.id.mainL);
u.setDrawingCacheEnabled(true);
LinearLayout z = (LinearLayout) findViewById(R.id.mainL);
int totalHeight = z.getHeight();
int totalWidth = z.getWidth();
u.layout(0, 0, totalWidth, totalHeight);
u.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(u.getDrawingCache());
u.setDrawingCacheEnabled(false);
obviously I'm not doing anything on quality but the result bitmap (that is a jpeg image) has a very bad quality.
what am I doing wrong?
I thing I should change it to a PNG Image somehow for better quality but I don't know how.
thanks.
Edit:
for those who ask where am I saving the bitmap I have to say that I'm not saving it at all. I just share it with this code:
String pathofBmp = MediaStore.Images.Media.insertImage(getContentResolver(), b , "title", null);
Uri bmpUri = Uri.parse(pathofBmp);
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/jpeg");
shareIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(Intent.createChooser(shareIntent, "Share"));
I have to say that I'm not saving it at all
Yes, you are. Otherwise, you would not have pathofBmp. Now, in your case, you are delegating everything about saving the bitmap to the MediaStore. I have never used insertImage() and I have no idea what it does in terms of file formats, quality percentage, etc.
If you want more control over saving the image, use compress() on Bitmap to write it to a file yourself.
please try this:
View v = view.getRootView();
v.setDrawingCacheEnabled(true);
Bitmap b = v.getDrawingCache();
String extr = Environment.getExternalStorageDirectory().toString();
File myPath = new File(extr, getString(R.string.free_tiket)+".jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
b.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
MediaStore.Images.Media.insertImage(getContentResolver(), b, "Screen", "screen");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I think problem is compress 100 is fix your problem.
reference

android storing blob in sqlite and retrieving it [duplicate]

This question already has answers here:
convert byteArray to bitmap retrieved from sqlite
(2 answers)
Closed 9 years ago.
I am storing image as byte array in sqlite database from one project.
Then i use the pre-populated table in another project
But the problem is that Bitmap Factory is resulting as null.
Code of storing images:
Bitmap myLogo = BitmapFactory.decodeResource(getResources(), arr[i]);
ByteArrayOutputStream stream1 = new ByteArrayOutputStream();
myLogo.compress(Bitmap.CompressFormat.JPEG, 100, stream1);
b = stream1.toByteArray();
Code of retrieving images:
BitmapFactory.Options options = new BitmapFactory.Options();
decodedByte = BitmapFactory.decodeByteArray(Image, 0,Image.length, options);
System.out.println("Image = " + Image);
System.out.println("decodedByte = " + decodedByte);
Here Image is returning the byteArray(Image) with length 12. But the bitmap(decodedByte) is returning null value.
I have tried a lot of ways but cannot find a solution. please help!
this is my function from bitmap to string
public String BitMapToString(Bitmap bitmap) {
try {
Bitmap encogida = Bitmap.createScaledBitmap(bitmap, 226, 180, true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
encogida.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
return org.kobjects.base64.Base64.encode(b);
} catch (Exception ex) {
Conexiones.escribirLog(Log.getStackTraceString(ex),
getString(R.string.versionReal));
Log.e("ERROR BitMapToString ", ""); // ex.getMessage());
return "";
}
}
I hope it helps
Have you tried decodeByteArray without the options parameter ? I think it's useless in this case.
Anyway, it's better to store image URI as String instead of a byte array in sqlite database.
To get URI :
String path = Images.Media.insertImage(getContentResolver(), mylogo,
"title", null);
Uri uriMyLogo = Uri.parse(path);
String uriString = uriMyLogo.toString() ;
And to get Image from URI
Uri uriLogo = Uri.parse(uriString);
Bitmap logo = null;
try {
logo = Media.getBitmap(this.getContentResolver(), uriLogo);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I hope it helps if you can't manage it as you want.

Bitmap in ListView: Loading slowly

In my ListView, I have one ImageView and two TextViews in every row. The pictures for the ListView are loaded from the memory of my Galaxy Nexus. I already downscaled it to 100x100 using
Bitmap scaled = Bitmap.createScaledBitmap(de, 80, 80, true);
but it still needs a few seconds to load.
What can I do?
EDIT:
public Bitmap resizeBitmap(String path){
BitmapFactory.Options options = new BitmapFactory.Options();
InputStream is = null;
try {
is = new FileInputStream(path);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
BitmapFactory.decodeStream(is,null,options);
try {
is.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
is = new FileInputStream(path);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// here w and h are the desired width and height
options.inSampleSize = Math.max(options.outWidth/100, options.outHeight/100);
// bitmap is the resized bitmap
Bitmap bitmap = BitmapFactory.decodeStream(is,null,options);
return bitmap;
}
First point i can see from your code that you are decoding the stream twice...the first place where it is decoded its not being even used anywhere....So removing that statement will increase the execution speed of your code.
//BitmapFactory.decodeStream(is,null,options); comment this line
try {
is.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Also may I ask why can you not use the Thumbnails of the pictures? instead of resizing every image....if you are trying to display thumbnails of images in your app
Yes there is a whole table that stores the thumbanil of images you need to access it via Cursor api for example:
Cursor mediaCursor = managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null,
null, null);
From this cursor you can get the imageId and then with the help of image Id you can retreive the thumbnail of the image by using the MediaStore.Images.Thumbnails.getThumbnail() method for example below is some code that will help:
Bitmap thumbBitmap = null;
thumbBitmap = MediaStore.Images.Thumbnails.getThumbnail(cr, imageID, MediaStore.Images.Thumbnails.MICRO_KIND, null);
if(thumbBitmap != null){
return new BitmapDrawable(thumbBitmap);
}
Displaying bitmaps in ListView efficiently is a fairly complex task that involves quite a lot of variables. I would suggest you reading this and downloading a code example they provide. This is an excellent starting point and in simple cases may be enough to be copy-pasted.
The best way is to load them in AsyncTask. Here you have a great video that shows this approach:
https://developers.google.com/events/io/2012/sessions/gooio2012/103/

Loading images from cache but return a blank screen

i try the example i gotten from here. The example shows how to display a image that is larger then the screen and the screen acting like a window, allowing user to look at the images via scrolling. However, what i want to achieved is similar just that, instead of one single image, i tried to combining 18 smaller images (171X205) into one single image. I am able to did that but to save loading time on downloading of images from the server, i cached the images. Heres the problem, i cant seems to display the images out on screen even though the images are indeed cached. Thus, i tried something else by fetching image from the drawable folder but still the same issue arise. Does anyone have any idea how to go about solving this problem?
A snippets of code to load images from cache:
for(int i =0; i<18; i++)
File cacheMap = new File(context.getCacheDir(), smallMapImageNames.get(i).toString());
if(cacheMap.exists()){
//retrieved from cached
try {
FileInputStream fis = new FileInputStream(cacheMap);
Bitmap bitmap = BitmapFactory.decodeStream(fis)
puzzle.add(bitmap);
}catch(...){}
}else{
Drawable smallMap = LoadImageFromWebOperations(mapPiecesURL.get(i).toString());
if(i==0){
height1 = smallMap.getIntrinsicHeight();
width1 = smallMap.getIntrinsicWidth();
}
if (smallMap instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable)smallMap).getBitmap();
FileOutputStream fos = null;
try {
cacheMap.createNewFile();
fos = new FileOutputStream(cacheMap);
bitmap.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
puzzle.add(bitmap);
}
}
}
The function where it retrieved images from the server
private Drawable LoadImageFromWebOperations(String url) {
// TODO Auto-generated method stub
try
{
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
return d;
}catch (Exception e) {
System.out.println("Exc="+e);
return null;
}
}
I am drawing onto a canvas and so no ImageView is use to display the images.
For all of my lazy image loading I use Prime.

Categories

Resources