At start up of my app I want to extract my images (if they does not exists) from drawable folder to internal app folder to use later with FileProvider. Images have dimensions 2000*2000 and average size 380kb, format png.
Those images are not to be displayed (smaller ones are used to display). They are only for file sharing and I have to keep their original size.
I get out of memory at calling
Bitmap bm = BitmapFactory.decodeResource(getResources(), imageResID);
Code
private void extractImages() {
TypedArray imgs = getResources().obtainTypedArray(R.array.smile_list_share);
File imagePath = new File(getFilesDir(), "images");
File checkImage;
for (int i = 0; i < imgs.length(); i++) {
int imageResID = imgs.getResourceId(i, 0);
if (imageResID > 0) {
String name = getResources().getResourceEntryName(imageResID);
checkImage = new File(imagePath, name + ".png");
if (!checkImage.exists()) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), imageResID);
boolean b = saveBitmapToFile(imagePath, name + ".png", bm, Bitmap.CompressFormat.PNG, 100);
Log.e("mcheck","saved "+b+", file "+name);
Log.e("mcheck", "file does not exists " + name);
} else {
Log.e("mcheck", "file exists " + name);
}
} else {
Log.e("mcheck", "ERROR " + i);
}
}
imgs.recycle();
}
public boolean saveBitmapToFile(File dir, String fileName, Bitmap bm,
Bitmap.CompressFormat format, int quality) {
File imageFile = new File(dir, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(imageFile);
bm.compress(format, quality, fos);
bm.recycle();
fos.close();
return true;
} catch (IOException e) {
Log.e("app", e.getMessage());
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return false;
}
You have to call recycle on your bitmap object everytime you are done with it.
Here is a good guide on how to manipulate bitmaps efficiently
https://developer.android.com/training/displaying-bitmaps/load-bitmap.html
I found that I dont need to create bitmap object at all. It is possible to obtaine intput stream from getResourses directly.
public boolean saveBitmapToFile(File dir, String fileName, int imageResourse) {
File imageFile = new File(dir, fileName);
FileOutputStream fos = null;
InputStream inputStream = null;
try {
fos = new FileOutputStream(imageFile);
inputStream = getResources().openRawResource(imageResourse);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
inputStream.close();
fos.close();
return true;
} catch (IOException e) {
Log.e("app", e.getMessage());
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return false;
}
Related
I am creating a custom print service in Android. When PDF is share to print service, it prints correctly but when image is shared it does not print as expected since it is corrupted. Below is method in my custom printservice. It saves PDF and image file. PDF file is fine and readable but image is corrupted after saved
private void handleHandleQueuedPrintJob(final PrintJob printJob) {
if (printJob.isQueued()) {
printJob.start();
}
int printType = printJob.getDocument().getInfo().getContentType();
if (printType == CONTENT_TYPE_DOCUMENT) {
String fName = MyHelper.getRandomString(8) + ".pdf";
File destFile = new File(getExternalFilesDir(MyConstants.FolderTemp), fName);
try {
InputStream in = new FileInputStream(printJob.getDocument().getData().getFileDescriptor());
FileOutputStream out = new FileOutputStream(destFile);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} else if (printType == CONTENT_TYPE_PHOTO) {
String fName = MyHelper.getRandomString(8) + ".jpg";
File destFile = new File(getExternalFilesDir(MyConstants.FolderTemp), fName);
InputStream in = new FileInputStream(printJob.getDocument().getData().getFileDescriptor());
FileOutputStream out = null;
try {
out = new FileOutputStream(destFile);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else
MyHelper.showLongToast(this, getString(R.string.invalidfiletype));
printJob.complete();
}
Can anybody help me why image is corrupted?
I want to render a pdf which in the raw folder with ParcelFileDescriptor tried too many methods from the other posts but none of them worked for me. Below is the code
I copied the code from the post you suggested and modified my code but still pdf is not opening even its showing no error.
public void render()
{
try
{
imgv = (ImageView) findViewById(R.id.img);
int w = imgv.getWidth();
int h = imgv.getHeight();
Bitmap bm = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_4444);
File fileBrochure = new File(Environment.getExternalStorageDirectory() + "/" + "abcd.pdf");
if (!fileBrochure.exists())
{
CopyAssetsbrochure();
}
/** PDF reader code */
File file = new File(Environment.getExternalStorageDirectory() + "/" + "abcd.pdf");
// File file = new File("android.resource://com.nyt.ilm.mytestpdfreader/raw/abcd.pdf");
PdfRenderer render = new PdfRenderer(ParcelFileDescriptor.open(file,ParcelFileDescriptor.MODE_READ_ONLY));
if (CurrentPage < 0)
{ CurrentPage =0;
}
else if (CurrentPage > render.getPageCount()){
CurrentPage = render.getPageCount() - 1;
}
Matrix m = imgv.getImageMatrix();
Rect rect = new Rect(0,0,w,h);
render.openPage(CurrentPage).render(bm,rect,m,PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
imgv.setImageMatrix(m);
imgv.setImageBitmap(bm);
imgv.invalidate();
}
catch (Exception e)
{
e.printStackTrace();
}
}
//method to write the PDFs file to sd card
private void CopyAssetsbrochure() {
AssetManager assetManager = getAssets();
String[] files = null;
try
{
files = assetManager.list("");
}
catch (IOException e)
{
Log.e("tag", e.getMessage());
}
for(int i=0; i<files.length; i++)
{
String fStr = files[i];
if(fStr.equalsIgnoreCase("abcd.pdf"))
{
InputStream in = null;
OutputStream out = null;
try
{
in = assetManager.open(files[i]);
out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/" + files[i]);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
break;
}
catch(Exception e)
{
Log.e("tag", e.getMessage());
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
I want to Save Image from res/drawable to Image Gallery. I am using following code but it is doing nothing.
What is the wrong with my code ? String Drawable stands for Image Name which is there in drawable folder.
File direct = new File(Environment.getExternalStorageDirectory()
+ "/Images");
if (!direct.exists()) {
direct.mkdirs();
}
ByteArrayOutputStream bos = null;
FileOutputStream fos = null;
try {
Bitmap bitmap = BitmapFactory.decodeResource(
context.getResources(),
context.getResources().getIdentifier(
"#drawable/" + Drawable, "drawable",
context.getPackageName()));
bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 95, bos);
byte[] bitmapdata = bos.toByteArray();
fos = new FileOutputStream(direct + "/" + "IMG-" + CurrentDateTime
+ ".jpg");
fos.write(bitmapdata);
} catch (Exception e) {
Log.e("Internal Image Save Error->", e.toString());
} finally {
try {
if (bos != null) {
bos.close();
}
if (fos != null) {
fos.close();
fos.flush();
}
} catch (IOException ignored) {
Log.e("Internal Image Save Error->", ignored.toString());
}
}
I just found that it is saving image but It is taking some time like 10 mins.
Copy Image from Drawable to Gallery : It is giving File Not Found Exception on Input Stream. String Drawable is image name, i.e. data1
public static void downloadInternalImage(String Drawable, Context context) {
Toast.makeText(context, "Downloading Image...\nPlease Wait.",
Toast.LENGTH_LONG).show();
File direct = new File(Environment.getExternalStorageDirectory()
+ "/Images");
if (!direct.exists()) {
direct.mkdirs();
}
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream("android.resource://"
+ context.getPackageName() + "/drawable/" + Drawable + "");
output = new FileOutputStream(direct + "/" + "IMG-"
+ CurrentDateTime + ".jpg");
byte[] buf = new byte[1024];
int len;
while ((len = input.read(buf)) > 0) {
output.write(buf, 0, len);
}
Toast.makeText(context, "Image Saved.", Toast.LENGTH_LONG).show();
} catch (Exception e) {
Log.e("Internal Image Save Error->", e.toString());
Toast.makeText(context,
"Couldn't Save Image.\nError:" + e.toString() + "",
Toast.LENGTH_LONG).show();
} finally {
try {
if (input != null) {
input.close();
}
if (output != null) {
output.close();
}
} catch (IOException ignored) {
Log.e("Internal Image Save Error->", ignored.toString());
Toast.makeText(
context,
"Couldn't Save Image.\nError:" + ignored.toString()
+ "", Toast.LENGTH_LONG).show();
}
}
}
I have .3gp audio file which is stored in SD Card.I want to copy that file into another folder of sd card.I have googled a lot about it but didn't get any working idea.Please help me if anyone knows.The code I have tried till now is given below:
private void save(File file_save) {
String file_path = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/RecordedAudio";
File file_dir = new File(file_path);
if (file_dir.exists()) {
file_dir.delete();
}
file_dir.mkdirs();
File file_audio = new File(file_dir, "audio"
+ System.currentTimeMillis() + ".3gp");
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = new ObjectOutputStream(bos);
out.writeObject(file_save);
out.close();
FileOutputStream fos = new FileOutputStream(file_audio);
byte[] buffer = bos.toByteArray();
fos.write(buffer);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This is always create a new file with the size of 100.Thanks in advance...
The code when i call this save() method is:
mFileFirst = new File(mFileName);//mFileName is the path of sd card where .3gp file is located
save(mFileFirst);
Try this
private void save(File file_save) {
String file_path = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/RecordedAudio";
File file_dir = new File(file_path);
if (file_dir.exists()) {
file_dir.delete();
}
file_dir.mkdirs();
File file_audio = new File(file_dir, "audio"
+ System.currentTimeMillis() + ".3gp");
try {
FileInputStream fis = new FileInputStream(file_save);
FileOutputStream fos = new FileOutputStream(file_audio);
byte[] buf = new byte[1024];
int len;
int total = 0;
while ((len = fis.read(buf)) > 0) {
total += len;
fos.write(buf, 0, len);
// Flush the stream once every so often
if (total > (20 * 1024)) {
fos.flush();
}
}
fos.flush();
fis.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
My app uses the following piece of code to write out images I have resized into the app's data folder:
private void writeImage(Bitmap bmp, String filename)
{
try
{
FileOutputStream stream = openFileOutput(filename, MODE_WORLD_WRITEABLE);
bmp.compress(CompressFormat.PNG, 100, stream);
stream.flush();
stream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
I am able to read them in a file browser (ddms) and can confirm they appear to have been written.
However, any attempt to load the images results in non-null bitmaps with width and height of -1. I am using the following code to load them:
imageList = getFilesDir().list();
Bitmap bmp = null;
for(String img : imageList)
{
try {
bmp = BitmapFactory.decodeStream(openFileInput(img));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
EDIT: On further inspection, it seems, after conversion the images are of density 160 (and not 240 as they should be) also, after testing a working application it seems the -1 mWidth and -1 mHeight on the bitmaps is irrelevent.
I had same problem.my data folder given smallest image.and cursor return null pointer exception on my getDestination method.then i fixed like it
public void captureNewPhoto() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
targetFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
targetUri = Uri.fromFile(targetFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, targetUri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, 12);
}
And i use like in onActivityResult();
BitmapFactory.Options options = new BitmapFactory.Options();
networkBitmap = BitmapFactory.decodeFile(targetUri.getPath(),
options);
//ImageDialog(networkBitmap);
//String path = getRealPathFromUri(this, Uri.parse(targetUri.getPath()));
String myDeviceModel = android.os.Build.MODEL;
deviceName = Build.MANUFACTURER;
if (myDeviceModel.equals("GT-I9500")) {
} else if (deviceName.contains("samsung")) {
} else {
exif = ReadExif(targetUri.getPath());
if (exif.equals("6")) {
matrixx.postRotate(90);
} else if (exif.equals("7")) {
matrixx.postRotate(-90);
} else if (exif.equals("8")) {
matrixx.postRotate(-90);
} else if (exif.equals("5")) {
matrixx.postRotate(-90);
}
//matrixx.postRotate(-90);
}
networkBitmap = Bitmap.createBitmap(networkBitmap, 0, 0, networkBitmap.getWidth(), networkBitmap.getHeight(), matrixx, true);
Log.e("Taget File ", "Size " + targetFile.length());
if (networkBitmap != null) {
ImageSetting(networkBitmap, System.currentTimeMillis() + filename);
}
public void ImageSetting(Bitmap imageBitmap, final String fileName) {
networkBitmap = imageBitmap;
organizator(networkBitmap, fileName);
networkBitmap = null;
}` public void tamamlandiOndenFoto(Bitmap turnedBitmap, String filename) {
frontFotoFile = storeBitmap(networkBitmap, filename);
ondenFotoPath = ondenFoto.getAbsolutePath();
ondenFotoImageView.setImageBitmap(turnedBitmap);
}`
public File storeBitmap(Bitmap bp, String fileName) {
File sd = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File dest = new File(sd, fileName);
if (bp != null) {
try {
FileOutputStream out = new FileOutputStream(dest);
bp.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
Log.e("Alinan hata ", " Catch hata ", e);
}
return dest;
} else {
return null;
}
}
I hope give you any idea for your problem.