scaled bitmap according to device resolution - android

I am getting strange issue of White blank screen when i try to set image inside my image view after scaling it from bitmap.
I am getting random size images from server , I just need to show them in my image view without loose in quality of image. i have taken one layout and add image view dynamically through code.
Here is what i am doing in code :-
Getting Url form server and scaling it accordingly :-
url="http://www.petstory.co/attached_king_photos/hotel/7/attached_d67e2689e0d3370f7e76b5bba9f8e875e42a2e39.jpg"
AsyncTask task = new AsyncTask<String, String, Bitmap>() {
Bitmap bitmap = null;
#Override
protected Bitmap doInBackground(String... params) {
bitmap = getBitmapFromURL(params[0]);
return bitmap;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (result.getHeight() > 7000){
getResizedBitmap(result, 4000, 4000, image);
}else{
getResizedBitmap(result, 800, 800, image);
}
}
}.execute(imageUrl);
public Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight, final ImageView image) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = bm.getWidth();
int height = bm.getHeight();
final int wantedgeightis = newHeight;
float scaleWidth = metrics.scaledDensity;
float scaleHeight = metrics.scaledDensity;
// float scaleWidth = ((float) newWidth) / width;
// float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
matrix.setRectToRect(new RectF(0, 0, bm.getWidth(), bm.getHeight()), new RectF(0, 0, newWidth, newHeight), Matrix.ScaleToFit.CENTER);
final Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
// final Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
//
if (wantedgeightis == 4000) {
image.setScaleType(ImageView.ScaleType.FIT_XY);
image.setImageBitmap(resizedBitmap);
} else {
int bitmapWidth = resizedBitmap.getWidth();
int bitmapHeight = resizedBitmap.getHeight();
final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, bitmapHeight);
image.setLayoutParams(params);
image.setPadding(10, 0, 10, 0);
image.setScaleType(ImageView.ScaleType.FIT_XY);
image.setImageBitmap(resizedBitmap);
}
}
});
return resizedBitmap;
}
The Url of image which i am setting in above methods is :-
http://www.petstory.co/attached_king_photos/hotel/7/attached_d67e2689e0d3370f7e76b5bba9f8e875e42a2e39.jpg
i am testing on nexus , rest images are aprearing as expected but only this image displays me white blank screen
I even make use of Glide and pisacco getting same issue for this image or sometimes highly distorted image get appear on screen.
Here is the code of Glide which i used :-
Glide.with(this) //passing context
.load(imageUrl) //passing your url to load image.
.placeholder(R.drawable.petzview_logo) //this would be your default image (like default profile or logo etc). it would be loaded at initial time and it will replace with your loaded image once glide successfully load image using url.
.error(R.drawable.petz_test)//in case of any glide exception or not able to download then this image will be appear . if you won't mention this error() then nothing to worry placeHolder image would be remain as it is.
.diskCacheStrategy(DiskCacheStrategy.ALL) //using to load into cache then second time it will load fast.
.fitCenter()//this method help to fit image into center of your ImageView
.dontAnimate()
.override(700, 4000)
.into(image);
I Even tried with bellow code too :-
Glide.with(this)
.load(imageUrl)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.placeholder(R.drawable.petzview_logo)
.dontAnimate()
.fitCenter()
.into(new ViewTarget<ImageView, GlideDrawable>(image) {
#Override
public void onResourceReady(GlideDrawable resource, GlideAnimation anim) {
Toast.makeText(HowAboutHere.this, "success", Toast.LENGTH_LONG).show();
image.setImageDrawable(resource.getCurrent());
}
#Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
Toast.makeText(HowAboutHere.this, "Glide image load failed for %s -> %s" + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
image.setVisibility(View.INVISIBLE);
}
});
By using .override(700, 4000) , the image is getting displayed but streched and if i change value to .override(700, 4100) , then blank white screen start getting displayed due to very large image size
Or Should i First Save image from URL to any file and then retrieve the image from file and apply inSample size bitmap algo on it this will be time taking and with utilize more memory and make application slow.As mentioned in below two links :-
Best method to download image from url in Android
Strange out of memory issue while loading an image to a Bitmap object
However here i am also posting the image look like when i use Bitmap code form displaying huge image from URL
As you can see the image is still getting stretched.
Any help will be appreciated
Thanks!!!

Related

Glide takes lot of time to load image in Image view

I am using glide to load image in image view but it is taking lot of time to show the image in image view. I am loading the picture from my custom camera in the image view. Every thing is working but it takes a lot of time to load the image here is the code:
private void show_image_from_custom_camera(byte[] data) {
bitmap_image = BitmapFactory.decodeByteArray(data, 0, data.length);
ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap_image.compress(Bitmap.CompressFormat.JPEG, 70, stream);
int screenWidth = width;
int screenHeight = height;
Glide.with(this)
.load(data)
.asBitmap().centerCrop()
.into(new SimpleTarget<Bitmap>(width,height) {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
// you can do something with loaded bitmap here
// .....
int w = resource.getWidth();
int h = resource.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
Bitmap realImage = Bitmap.createBitmap(resource, 0, 0, w, h, mtx, true);
photo_setter.setImageBitmap(realImage); //setting the image in image-view
}
});
}
Is there anything that will reduce this time? I want to show image in image view at a faster rate.
Thanks to Belzebub .Well I am have made a serious mistake and I forgot to remove the first 3 line of the code that are :
bitmap_image = BitmapFactory.decodeByteArray(data, 0, data.length);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap_image.compress(Bitmap.CompressFormat.JPEG, 70, stream);
Without them everything is working fine and I am loading image in image view with faster speed now I am keeping this post so that anyone wants to load image in image view on Camera.PictureCallback can use this code without the top 3 lines.

Android load resized image from asset

I am getting memory error in my android game and i think its caused by my image loading function. everything is working fine on my mobile but on tablet i get memory exceed error.
I am using a matrix because i need to resize the image to a float value. But in this case i have to load the image in full size first and then resize it with the matrix and i think this causes the memory error.
is this the correct way to handle image resize?
public class Sprite {
private Bitmap bitmap = null;
private float scaleX, scaleY;
public Sprite(String path, float targetWidth, float targetHeight, Context context) {
InputStream istr;
AssetManager assetManager = context.getAssets();
Matrix scalematrix = new Matrix();
try {
istr = assetManager.open(path);
bitmap = BitmapFactory.decodeStream(istr);
scaleX = targetWidth / bitmap.getWidth();
scaleY = targetHeight / bitmap.getHeight();
scalematrix.postScale(scaleX, scaleY);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), scalematrix, true);
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}
BitmapFactory.Options has public int inSampleSize -- If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory.
You may try to use BitmapFactory.decodeXXX(..., BitmapFactory.Options opts) (decodeFile() etc.)

How to load video thumbnails using square picasso library?

Currently I'm loading MediaStore Image Thumbnails using picasso into the ListView with the following snippet: (video.getData() returns the actual path of the image such as mnt/sdcard/...)
Picasso.with(this.context)
.load(new File(photo.getData()))
.resize(50, 50).config(config)
.centerCrop()
.into(viewHolder.imageViewItem);
Now I'm and unable to load the MediaStore Video Thumbnails by just passing the video.getData() instead of photo.getData()?
First You need to create VideoRequestHandler
public class VideoRequestHandler extends RequestHandler{
public String SCHEME_VIDEO="video";
#Override
public boolean canHandleRequest(Request data)
{
String scheme = data.uri.getScheme();
return (SCHEME_VIDEO.equals(scheme));
}
#Override
public Result load(Request data, int arg1) throws IOException
{
Bitmap bm;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
try {
Size size = new Size(250, 250);
bm = ThumbnailUtils.createVideoThumbnail(new File(data.uri.getPath()), size, null);
} catch (IOException e) {
e.printStackTrace();
}
}
else
{
bm = ThumbnailUtils.createVideoThumbnail(data.uri.getPath(), MediaStore.Images.Thumbnails.MINI_KIND);
}
return new Result(bm,LoadedFrom.DISK);
}
}
After That
VideoRequestHandler videoRequestHandler;
Picasso picassoInstance;
Build only once
videoRequestHandler = new VideoRequestHandler();
picassoInstance = new Picasso.Builder(context.getApplicationContext())
.addRequestHandler(videoRequestHandler)
.build();
Then load file from path
picassoInstance.load(VideoRequestHandler.SCHEME_VIDEO+":"+filepath).into(holder.videoThumbnailView);
Updated October 2020
ThumbnailUtils.createVideoThumbnail(data.uri.getPath(), MediaStore.Images.Thumbnails.MINI_KIND);
is deprecated in Android Q. I will write in Kotlin:
val bm = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ThumbnailUtils.createVideoThumbnail(
File(data.uri.path!!),
Size(200f.toPx(), 200f.toPx()),
CancellationSignal()
)
} else {
ThumbnailUtils.createVideoThumbnail(
data.uri.path!!,
MediaStore.Images.Thumbnails.MINI_KIND
)
}
to Px is an extension function which is like below;
fun Float.toPx() =
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, Resources.getSystem().displayMetrics)
.toInt()
You can use any dp value for it :) I hope this can help you :)
Before, you had two options:
1) Do a call beforehand, when you were retrieving your videos for example and storing the bitmap:
Bitmap thumbnailBitmap = MediaStore.Video.Thumbnails.getThumbnail(content, id, MediaStore.Video.Thumbnails.MINI_KIND, options);
2) Creating a custom Downloader (not verified for local media)
But now, with Picasso 2.4, you can create a RequestHandler. You can have a look at this page for example: http://blog.jpardogo.com/requesthandler-api-for-picasso-library/
In my current usage, I fetch the thumbnail path and then call Picasso with that path. To get the thumbnail path, I referred to: android get video thumbnail PATH, not Bitmap.
public void bindTo(MediaListHolder mediaListRowHolder, int i) {
DataPictures message = itemList.get(i);
try {
Uri uri = Uri.fromFile(new File(message.getFilePath()));
if (message.getFileType().equalsIgnoreCase("video")) {
Bitmap bmThumbnail = ThumbnailUtils.extractThumbnail(ThumbnailUtils.createVideoThumbnail(message.getFilePath(),
MediaStore.Video.Thumbnails.FULL_SCREEN_KIND), MAX_WIDTH, MAX_HEIGHT);
mediaListRowHolder.thumbnail.setImageBitmap(bmThumbnail);
} else {
Picasso.with(ApplicationSingleton.getInstance()).load(uri)
.resize(size, size)
.placeholder(R.drawable.logo_slogan)
.into(mediaListRowHolder.thumbnail);
}
Log.i(TAG, "bindTo: ");
} catch (Exception e) {
e.printStackTrace();
}
}
Note - Follow this comment if you simply want to show thumbnail in your image view and apply no extra Picasso functions on it .
I just modified it a little to show circular thumbnail coz it looks cool .
Don't use Picasso . Here's a very simple way to do it .
videoPathUrl = /*your Video File Url */
Bitmap bMap = ThumbnailUtils.createVideoThumbnail(videoPathUrl , MediaStore.Video.Thumbnails.MICRO_KIND);
bMap = transformBitmapToCircularBitmap(bMap);
yourImageView.setImageBitmap(bMap);
and transformBitmapToCircularBitmap function is as follows -
public static Bitmap transformBitmapToCircularBitmap(Bitmap source)
{
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap,
BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
squaredBitmap.recycle();
return bitmap;
}

Fast load image from sdcard

I want that load images from sdcard to listview but i dont need image in big size. size 60dip * 60dip is Sufficient. i am using below codes in thread but however this is slow.i need load images in fast way.
public Bitmap loadImage(String imagePath){
//load bitmap in real size
Bitmap bmp = BitmapFactory.decodeFile(imagePath);
int width = bmp.getWidth();
int height = bmp.getHeight();
//determine size and scale
float newWidth = convertDipToPixel(60, getApplicationContext());//60 dip
float scale = ((float) newWidth) / width;
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scale, scale);
Bitmap resizedBitmap = Bitmap.createBitmap(bmp, 0, 0, width, height, matrix, true);
return resizedBitmap;}
check android query and image loading using android query
its really fast, try it.
File file = new File(path);
//load image from file, down sample to target width of 300 pixels
aq.id(R.id.avatar).image(file, 300);
you can also use Android-Universal-Image-Loader
String imageUri = "file:///mnt/sdcard/image.png"; // from SD card
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view
// which implements ImageAware interface)
imageLoader.displayImage(imageUri, imageView);

How to resize bitmap decoded from URL?

I am using bitmap to get a image from a url using this
public void loadImage(String url){
try {
bitmap = BitmapFactory.decodeStream((InputStream)new URL(url).getContent());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Is there anyway i can resize the image from here? setting the width and the height of it still keeping the resolution?
Use: Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)
You can try this too.
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 1; // 1 = 100% if you write 4 means 1/4 = 25%
bitmap = BitmapFactory.decodeStream((InputStream)new URL(url).getContent(),
null, bmOptions);
bmImage.setImageBitmap(bitmap);
Maybe this will help you:
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
You can just use Picasso(very simple!):
Picasso.with(context) .load(url) .resize(10, 10) .into(imageView)
http://square.github.io/picasso/
why don't you set the width and height property of imageView in XML?
I find out that the image from url is resized automatically so that it can fit in that imageView.
I needed similar capabilities in my app also. I found the best solution for me here.
https://github.com/coomar2841/image-chooser-library/blob/dev/src/com/kbeanie/imagechooser/threads/MediaProcessorThread.java
You might not need all that functionality, but at some point the guy is compressing /scaling bitmaps.

Categories

Resources