actually i'm opening png files from assets folder with this code:
public static Bitmap loadImage( String imageName ){
if( imageName.charAt(0) == '/' ) {
imageName = imageName.substring(1);
}
imageName = imageName + ".png";
Bitmap image = BitmapFactory.decodeStream(getResourceAsStream(imageName));
return image;
}
public static InputStream getResourceAsStream( String resourceName ) {
if( resourceName.charAt(0) == '/' ) {
resourceName = resourceName.substring(1);
}
InputStream is = null;
try {
is = context.getAssets().open( resourceName );
} catch (IOException e) {e.printStackTrace();}
return is;
}
This code opens the bitmaps with full cuality and it takes a lot of time to open it. I will try to use RGB_565 to speed up the opening of the bitmap.
What should i change into my code to open the bitmap with RGB_565? As you can see, i dont know the width and the height of the image.
Also any sugerences to speed up the opening of the bitmap will be welcome
Thanks
Add BitmapFactory.Options to to decodeStream() call:
BitmapFactory.Options bitmapLoadingOptions = new BitmapFactory.Options();
bitmapLoadingOptions.inPreferredConfig = Bitmap.Config.RGB_565;
BitmapFactory.decodeStream(instream,null,bitmapLoadingOptions);
As for how to speed up loading the image? Not sure what else you can do except maybe reduce the size of the image if that's possible.
This code worked for me
AssetManager assetManager = getAssets();
InputStream istr = null;
try {
istr = assetManager.open(strName);
} catch (IOException e) {
e.printStackTrace();
}
BitmapFactory.Options bitmapLoadingOptions = new BitmapFactory.Options();
bitmapLoadingOptions.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeStream(istr,null,bitmapLoadingOptions);
return bitmap;
Related
Trying to upload image as file using Retrofit, have uploaded files when path was of type file:// but now due to naugat , have changed the path Uri to Content:/ type, now when i convert this path to file and make retrofit Call, it gives FileNotFoundException
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"),photoFile);
this is the value of photoFile used above- file:/storage/emulated/0/Android/data/com.Bawa.Sketches/files/Pictures/JPEG_20161114_063716_-1561886067.jpg
USed setPic() method given in developer's site
private void setPic(ImageView sketchIv) {
InputStream input = null;
try {
input = getContentResolver().openInputStream(Uri.parse(mCurrentPhotoPath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// Get the dimensions of the View
int targetW = 300;
int targetH = 300;
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(input, null, bmOptions);
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
try {
input = getContentResolver().openInputStream(Uri.parse(mCurrentPhotoPath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bmOptions);
sketchIv.setImageBitmap(bitmap);
compressImage(bitmap);
//showAlertDialog(bitmap);
}
called CompressImage() method to reduce size of the image and got the photoFile value in the method
private void compressImage(Bitmap lbitmap) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
File f = new File(Uri.parse(mCurrentPhotoPath).toString());
try {
f.createNewFile();
Bitmap bitmap = lbitmap;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, bos);
byte[] bitmapdata = bos.toByteArray();
FileOutputStream fos = null;
fos = new FileOutputStream(f);
fos.write(bitmapdata);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
}
photoFile = f;
Log.i("response","FILE : "+ f);
}
P.S. have read Commonsware's answer most of the places - If you get a content:// Uri, please consume it using a ContentResolver and methods like openInputStream() and openOutputStream().
do not have any idea how to implement this.
called CompressImage() method to reduce size of the image and got the photoFile value in the method
We discussed this previously.
File f = new File(Uri.parse(mCurrentPhotoPath).toString());
Uri.parse(mCurrentPhotoPath).toString() will give you mCurrentPhotoPath back, as parse() and toString() undo each other. And mCurrentPhotoPath is a string representation of a Uri, not a filesystem path.
So, modify compressImage() to use the same InputStream approach that you used in setPic().
check this code,Create a typed file using your image path. I think it will work.
TypedFile typedFile = new TypedFile("image/jpeg", new File(photoFile ));
or
if you are using retrofit version above 2 then you can you use following code.
RequestBody file = RequestBody.create(MediaType.parse("image/*"), photoFile );
i need to load a image from assets to avoid a froyo 2.2.2 bug resizing POT images in some particular cases. The way to avoid it is loading the image files from assets dir.
I'm trying to do with this:
String imagePath = "radiocd5.png";
AssetManager mngr = context.getAssets();
// Create an input stream to read from the asset folder
InputStream is = null;
try {
is = mngr.open(imagePath);
} catch (IOException e1) { e1.printStackTrace();}
//Get the texture from the Android resource directory
//InputStream is = context.getResources().openRawResource(R.drawable.radiocd5);
Bitmap bitmap = null;
try {
//BitmapFactory is an Android graphics utility for images
bitmap = BitmapFactory.decodeStream(is);
} finally {
//Always clear and close
try {
is.close();
is = null;
} catch (IOException e) {}
}
But i am getting NullPointerException on the line is.close();
i capture a FileNotFoundException: radiocd5.png, but that file is on my assets directory :S
What am i doing bad? The file is called radiocd5.png and it is on the assets directory
You can follow my tutorials on displaying data from Assets: https://xjaphx.wordpress.com/2011/10/02/store-and-use-files-in-assets/
The sample with loading image and text to display.
I now added the relevant part of the provided link
(in case of earthquake or something) ;-) Taifun
// load image
try {
// get input stream
InputStream ims = getAssets().open("avatar.jpg");
// load image as Drawable
Drawable d = Drawable.createFromStream(ims, null);
// set image to ImageView
mImage.setImageDrawable(d);
}
catch(IOException ex) {
return;
}
Instead of using the assets dir, put the file into /res/raw, and you can then access it using the following URI: android.resource://com.your.packagename/" + R.raw.radiocd5
try {
InputStream istr = this.context.getAssets().open(P.strImage);
//set drawable from stream
this.imgProduct.setImageDrawable(Drawable.createFromStream(istr, null));
} catch (IOException e) {
e.printStackTrace();
}
protected String openImageInAssets(String imageName) {
String encodedImageBase64 = "";
AssetManager assetManager = getAssets();
InputStream fileStream = null;
try {
fileStream = assetManager.open(imageName);
if (fileStream != null) {
// BitmapFactory.Options bfo = new BitmapFactory.Options();
// bfo.inPreferredConfig = Bitmap.Config.ARGB_8888;
// Bitmap bitmap = BitmapFactory.decodeStream(fileStream, null, bfo);
Bitmap bitmap = BitmapFactory.decodeStream(fileStream);
// Convert bitmap to Base64 encoded image for web
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// to get image extension file name split the received
int fileExtensionPosition = imageName.lastIndexOf('.');
String fileExtension = imageName.substring(fileExtensionPosition+1);
// Log.d(IConstants.TAG,"fileExtension: " + fileExtension);
if (fileExtension.equalsIgnoreCase("png")) {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
// Log.d(IConstants.TAG,"fileExtension is PNG");
} else if (fileExtension.equalsIgnoreCase("jpg") || fileExtension.equalsIgnoreCase("jpeg")) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
// Log.d(TAG,"fileExtension is JPG");
}
byte[] byteArray = byteArrayOutputStream.toByteArray();
String imgageBase64 = Base64.encodeToString(byteArray, Base64.DEFAULT);
encodedImageBase64 = "data:image/png;base64," + imgageBase64;
}
} catch (IOException e) {
e.printStackTrace();
return encodedImageBase64="";
} finally {
//Always clear and close
try {
if (fileStream != null) {
fileStream.close();
fileStream = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
// Log.d(TAG,"encodedImageBase64: " + encodedImageBase64);
return encodedImageBase64;
}
Here is an alternative way
setImageBitmap(BitmapFactory.decodeStream(assets.open("photo.jpg")))
Another version, inside a fragment:
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.createrestaurant_layout, container, false);
Resources res = getResources();
img = (ImageView) root.findViewById(R.id.img);
AssetManager amanager = res.getAssets();
try {
InputStream imageStream = amanager.open("restaurant.jpg");
Drawable drawable = new BitmapDrawable(res, imageStream);
img.setImageDrawable(drawable);
} catch (Exception e) {
e.printStackTrace();
}
}
This process seems much simpler in iOS/UIKit or iOS/SwiftUI.
I am using BitmapFactory.decodeStream(inputStream) to create a bitmap. But the size of the bitmap returned by bitmap.getByteCount() is coming out be very huge compared to the actual image size. The actual image size when I download(on disk) is around 36kb, but the bitmap generated has a size of around 800kb. Since it is the same image, how come there is such a huge difference ? I am using the following piece of code.
Bitmap.Config.RGB_565 is helping me to reduce the size of the image
public Bitmap downloadImage(String imageUrl) {
Bitmap bitmap = null;
InputStream inputStream = null;
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
inputStream = (new URL(imageUrl)).openStream();
bitmap = BitmapFactory.decodeStream(inputStream, null, options);
Log.d("downloadImage","size of downloaded image " + bitmap.getByteCount()/1024);
return bitmap;
} catch (Exception e) {
}
finally {
try {
if(inputStream != null) {
inputStream.close();
}
} catch(Exception e) {
}
}
return bitmap;
}
I'm having an issue whereby when I write a bitmap to disk, it gets written to disk, however it gets written as a miniscule image (3kb or less in filesize).
I have checked that the source image is indeed the correct dimensions, however the output image seems shrunk despite configuring the bitmap options to not scale.
#Override
protected Void doInBackground(PPImage... params) {
String filename = "pp_" + position + ".jpg";
File externalStorageDirectory = Environment.getExternalStorageDirectory();
final File destination = new File(externalStorageDirectory, filename);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 16;
opts.inPurgeable = true;
opts.inScaled = false;
decode(opts, Uri.parse(params[0].getUri()), getActivity(), new OnBitmapDecodedListener() {
#Override
public void onDecoded(Bitmap bitmap) {
try {
FileOutputStream out = new FileOutputStream(destination, false);
writeImageToFileTask.this.holder.pathToImage = destination.getAbsolutePath();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
MediaStore.Images.Media.insertImage(getActivity().getContentResolver(), destination.getAbsolutePath(), destination.getName(), destination.getName());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
});
return null;
}
private void decode(BitmapFactory.Options options, Uri mUri, Context mContext, OnBitmapDecodedListener listener) {
try {
InputStream inputStream;
if (mUri.getScheme().startsWith("http") || mUri.getScheme().startsWith("https")) {
inputStream = new URL(mUri.toString()).openStream();
} else {
inputStream = mContext.getContentResolver().openInputStream(mUri);
}
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
listener.onDecoded(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
How do I ensure that the image being written to file is the same dimensions as the original source image?
You have specified sample size in your code, which will result in resizing:
opts.inSampleSize = 16;
Just remove this line, and the dimension of the output image should be the same.
About the usage of inSampleSize, according to official doc:
For example, inSampleSize == 4 returns an image that is 1/4 the
width/height of the original, and 1/16 the number of pixels. Any value
<= 1 is treated the same as 1.
i need to load a image from assets to avoid a froyo 2.2.2 bug resizing POT images in some particular cases. The way to avoid it is loading the image files from assets dir.
I'm trying to do with this:
String imagePath = "radiocd5.png";
AssetManager mngr = context.getAssets();
// Create an input stream to read from the asset folder
InputStream is = null;
try {
is = mngr.open(imagePath);
} catch (IOException e1) { e1.printStackTrace();}
//Get the texture from the Android resource directory
//InputStream is = context.getResources().openRawResource(R.drawable.radiocd5);
Bitmap bitmap = null;
try {
//BitmapFactory is an Android graphics utility for images
bitmap = BitmapFactory.decodeStream(is);
} finally {
//Always clear and close
try {
is.close();
is = null;
} catch (IOException e) {}
}
But i am getting NullPointerException on the line is.close();
i capture a FileNotFoundException: radiocd5.png, but that file is on my assets directory :S
What am i doing bad? The file is called radiocd5.png and it is on the assets directory
You can follow my tutorials on displaying data from Assets: https://xjaphx.wordpress.com/2011/10/02/store-and-use-files-in-assets/
The sample with loading image and text to display.
I now added the relevant part of the provided link
(in case of earthquake or something) ;-) Taifun
// load image
try {
// get input stream
InputStream ims = getAssets().open("avatar.jpg");
// load image as Drawable
Drawable d = Drawable.createFromStream(ims, null);
// set image to ImageView
mImage.setImageDrawable(d);
}
catch(IOException ex) {
return;
}
Instead of using the assets dir, put the file into /res/raw, and you can then access it using the following URI: android.resource://com.your.packagename/" + R.raw.radiocd5
try {
InputStream istr = this.context.getAssets().open(P.strImage);
//set drawable from stream
this.imgProduct.setImageDrawable(Drawable.createFromStream(istr, null));
} catch (IOException e) {
e.printStackTrace();
}
protected String openImageInAssets(String imageName) {
String encodedImageBase64 = "";
AssetManager assetManager = getAssets();
InputStream fileStream = null;
try {
fileStream = assetManager.open(imageName);
if (fileStream != null) {
// BitmapFactory.Options bfo = new BitmapFactory.Options();
// bfo.inPreferredConfig = Bitmap.Config.ARGB_8888;
// Bitmap bitmap = BitmapFactory.decodeStream(fileStream, null, bfo);
Bitmap bitmap = BitmapFactory.decodeStream(fileStream);
// Convert bitmap to Base64 encoded image for web
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// to get image extension file name split the received
int fileExtensionPosition = imageName.lastIndexOf('.');
String fileExtension = imageName.substring(fileExtensionPosition+1);
// Log.d(IConstants.TAG,"fileExtension: " + fileExtension);
if (fileExtension.equalsIgnoreCase("png")) {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
// Log.d(IConstants.TAG,"fileExtension is PNG");
} else if (fileExtension.equalsIgnoreCase("jpg") || fileExtension.equalsIgnoreCase("jpeg")) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
// Log.d(TAG,"fileExtension is JPG");
}
byte[] byteArray = byteArrayOutputStream.toByteArray();
String imgageBase64 = Base64.encodeToString(byteArray, Base64.DEFAULT);
encodedImageBase64 = "data:image/png;base64," + imgageBase64;
}
} catch (IOException e) {
e.printStackTrace();
return encodedImageBase64="";
} finally {
//Always clear and close
try {
if (fileStream != null) {
fileStream.close();
fileStream = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
// Log.d(TAG,"encodedImageBase64: " + encodedImageBase64);
return encodedImageBase64;
}
Here is an alternative way
setImageBitmap(BitmapFactory.decodeStream(assets.open("photo.jpg")))
Another version, inside a fragment:
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.createrestaurant_layout, container, false);
Resources res = getResources();
img = (ImageView) root.findViewById(R.id.img);
AssetManager amanager = res.getAssets();
try {
InputStream imageStream = amanager.open("restaurant.jpg");
Drawable drawable = new BitmapDrawable(res, imageStream);
img.setImageDrawable(drawable);
} catch (Exception e) {
e.printStackTrace();
}
}
This process seems much simpler in iOS/UIKit or iOS/SwiftUI.