I am using Mapbox in my application so I'm displaying customizing marker in the map.I will get image from API as image URL,if I directly pass the url image is not displying so I converted as the Bitmap image,sometimes applciation getting crashed.Please help me.
java.lang.OutOfMemoryError: Failed to allocate a 53934348 byte allocation with 4194208 free bytes and 36MB until OOM
Note:while converting the url into bitmap that time itself application crashed sometimes.
Code:
//converting the url into bitmap
try {
URL url = new URL(“http://192.168.0.109/images/profile/2018-04-03-14-01-022017-11-13-07-12-36Image.jpg”);
Bitmap bitmapimage = BitmapFactory.decodeStream(url.openConnection().getInputStream()); }
catch(IOException e) { System.out.println(e); }
//customizing the marker
MarkerViewOptions markerViewOptions = new MarkerViewOptions()
.position(new LatLng(Double.parseDouble(userDetails.getLatitude()), Double.parseDouble(userDetails.getLongitutde())))
.icon(drawableToIcon(getContext(),bitmapimage, userDetails.getUser_status()));
mMapBoxMap.addMarker(markerViewOptions);
//method to customise the layout
public Icon drawableToIcon(#NonNull Context context, Bitmap image, String status) {
View marker = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.custom_marker_layout, null);
CircleImageView markerImage = (CircleImageView) marker.findViewById(R.id.user_dp);
markerImage.setImageBitmap(image);
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
marker.setLayoutParams(new ViewGroup.LayoutParams(52, ViewGroup.LayoutParams.WRAP_CONTENT));
marker.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
marker.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
marker.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(marker.getMeasuredWidth(), marker.getMeasuredHeight(), Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(bitmap);
marker.draw(canvas);
return IconFactory.getInstance(context).fromBitmap(bitmap);
}
I referred this link http://madhusudhanrc.blogspot.in/2012/09/reduce-bitmap-size-using.html ,if I shrink the image means its not diplaying.Please help me to reduce the bitmap size.
Related
I take a fingerprint from the user and add white background to it using glide. The issue is I need to get the byte array of that image and I can't get it because the Image being hold into the ImageView is a VectorDrawable. I am unable to convert this back to bitmap and thus to a byte array. I tried using it on a dummy png image like following.
Take any dummy PNG Image
firstIV = findViewById(R.id.firstIV);
secondIV = findViewById(R.id.secondIV);
Bitmap currentBmp = BitmapFactory.decodeResource(getResources(), R.drawable.test_image);
Glide.with(this).load(currentBmp).into(new SimpleTarget<Drawable>() {
#Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> glideAnimation) {
final ShapeDrawable background = new ShapeDrawable();
background.getPaint().setColor(Color.WHITE);
final Drawable[] layers = {background, resource};
firstIV.setImageDrawable(new LayerDrawable(layers));
setToAnotherImageView(firstIV.getDrawable().getIntrinsicWidth(), firstIV.getDrawable().getIntrinsicHeight());
}
});
Applied Solution
private void setToAnotherImageView(int width, int height) {
Log.e(TAG, "onCreate: " + width + ":" + height);
Bitmap convertedBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(convertedBmp);
firstIV.draw(canvas);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
convertedBmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Bitmap newBmp = BitmapFactory.decodeByteArray(byteArray,0,byteArray.length);
secondIV.setImageBitmap(newBmp);
}
Upon doing so my app crashes with an exception saying the vector drawable can not be converted to bitmap. The following is the error:
Originally what I want to achieve
Originally I want the bytearray of the the picture I have stored in my ImageView so I can convert that bytearray to WSQ bytearray and the send it to my server. I am trying to achieve such with an example defined above.
UPDATE:
Just find out that there is a new way to get Bitmap from ImageView:
imageView.drawToBitmap() //draw from the ImageView size
imageView.drawable.toBitmap() //draw from original Drawable size (I guess)
Convert ImageView to ByteArray:
private fun getImageBytes(): ByteArray {
val bitmap = Bitmap.createBitmap(my_profile_imageView.width, my_profile_imageView.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
my_profile_imageView.draw(canvas)
val outputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
return outputStream.toByteArray()
}
However, it's not a good idea to store the image ByetArray in local, you should store the uri or url instead.
My question is a duplicate of How to get a Bitmap from VectorDrawable
However I solved it like this
private void setToAnotherImageView() {
Drawable drawable = firstIV.getDrawable();
Bitmap newBmp = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBmp);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
secondIV.setImageBitmap(newBmp);
}
I'm using Map in my application so I'm customising the marker in my map. When application opens if I give image url directly its not displaying so I'm converting into bitmap.
sometimes application getting crashes. I referred many links but I didn't get proper code.
Issues:
Fatal Exception: java.lang.OutOfMemoryError
Failed to allocate a 55987212 byte allocation with 4194208 free bytes and 17MB until OOM
Fatal Exception: java.lang.OutOfMemoryError at android.graphics.BitmapFactory.nativeDecodeStream(BitmapFactory.java)
code:
try {
URL url = new URL("http://default-environment.8ed3pmbznb.ap-south-1.elasticbeanstalk.com/images/profile/2018-04-03-14-01-022017-11-13-07-12-36Image.jpg");
Bitmap bitmapimage = BitmapFactory.decodeStream(url.openConnection().getInputStream());
Bitmap scaled = Bitmap.createScaledBitmap(bitmapimage, 100, 100, true);
//scaled = BitmapFactory.decodeFile(ServerUtils.Gs_ImagePath+gs_var_user_image);
}
catch(IOException e) {
System.out.println(e);
}
Setting image in marker:
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
mMarker = new MarkerOptions()
.position(latLng)
.icon(BitmapDescriptorFactory.fromBitmap(drawableToIcon(getContext(),scaled, Is_active)));
mMap.addMarker(mMarker);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(14));
customizing marker in layout
public Bitmap drawableToIcon(#NonNull Context context, Bitmap image, String status) {
View marker = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.custom_marker_layout, null);
ImageView rlay = (ImageView) marker.findViewById(R.id.imageView1);
markerImage.setImageBitmap(image);
marker.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
marker.layout(0, 0, marker.getMeasuredWidth(), marker.getMeasuredHeight());
marker.buildDrawingCache();
Bitmap returnedBitmap = Bitmap.createBitmap(marker.getMeasuredWidth(), marker.getMeasuredHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
canvas.drawColor(Color.WHITE, PorterDuff.Mode.SRC_IN);
Drawable drawable = marker.getBackground();
if (drawable != null)
drawable.draw(canvas);
marker.draw(canvas);
return returnedBitmap;
}
If I set the image url directly into marker, first time is not loading, when refresh page only showing that'y I converting as bitmap. Even though i reduced the bitmap size also using this
createScaledBitmap(bitmapimage, 100, 100, true);
Anyone can reply me please
Bitmap scaled = Bitmap.createScaledBitmap(bitmapimage, 100, 100, true);
That is the wrong approach as before you create that big bitmap `bimapimage' that already caused the oom.
Instead you should use decodeStream with a scale options parameter so you will directly get a small bitmap.
I want to get the picture of the view(not ImageView) inside,but the picture I got was not clear,Of course the original picture is clear ,here is my codes
public static Bitmap getDrawBitmap(View designView){
designView.destroyDrawingCache();
designView.setDrawingCacheEnabled(true);
designView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
return designView.getDrawingCache();
}
I have tried to scale the View,and then getDrawingCache(),but it didn't work,the view's size didn't change
Bitmap bitmap=ImgUtils.getDrawBitmap(testBtn);
float w=1260f;
float h=1660f;
float x= w/(bitmap.getWidth()/DrawAttribute.density);
float y= h/(bitmap.getHeight()/DrawAttribute.density);
Log.e("x-y",x+"-"+y);
Bitmap result=Bitmap.createBitmap(1260,1660,Bitmap.Config.ARGB_8888);
Canvas offScreen = new Canvas(result);
Matrix matrix=new Matrix();
matrix.setScale(x,y);
offScreen.drawBitmap(bitmap, matrix, null);
//存储路径
OutputStream stream = null;
try {
if (LiApplication.creatDir()) {
stream = new FileOutputStream(Environment.getExternalStorageDirectory()+ "/yc/img/"
+ "save.png");
}
} catch (FileNotFoundException e) {
}
Bitmap.CompressFormat format = Bitmap.CompressFormat.PNG;
result.compress(format, 100, stream);
This is a Demo code for taking screen shot of whole View.
View v = (View) findViewById(R.id.myView);
Bitmap mybitmap = Bitmap.createBitmap(
v.getChildAt(0).getWidth(),
v.getChildAt(0).getHeight(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(mybitmap);
iv.getChildAt(0).draw(c);
//remember here View may be any view including ScrollView or what ever it may be.
saveBitmap(bitmap);
Hope this will help. Thanks
Am drawing a graph using AChartEngine where I'm having text (i.e. annotations, as they call in AChartEngine). They appear fine when seen on the screen, as you can see below :
but when the screen is saved as bitmap, the text appears with only the outline of each letter displayed as you can see below :
and this is how I get the bitmap from the view (ie. I am taking a screenshot of the graph)
Bitmap bitmap;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
options.inInputShareable = true;
Bitmap dummy = null;
try {
dummy = BitmapFactory.decodeStream(context.getAssets().open("icon_add.png"), new Rect(-1,-1,-1,-1), options);
} catch (IOException e) {
e.printStackTrace();
}
bitmap = Bitmap.createBitmap(deviceWidth,
deviceHeight, Bitmap.Config.ARGB_8888); // use ARGB_4444 if outofmemory
Canvas c = new Canvas(bitmap);
c.drawColor(Color.WHITE);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight() + 15);
view.draw(c);
can someone please help?
This code works for me:
Bitmap cache;
view.buildDrawingCache();
cache = Bitmap.createBitmap(view.getDrawingCache());
view.destroyDrawingCache();
I'm working with a set of layered images (think stacked) and I need to combine them into one element.
I'm basing my solution off Combine multiple bitmap into one
//send a map to the method that has my stored image locations in order
private Bitmap combineImageIntoOne(NavigableMap<Integer, String> layerImages) {
//size of my bitmaps
int w = 400, h = 400;
//bitmap placeholder
Bitmap productIndex = null;
//flattened layers
Bitmap temp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
//canvas to write layers to
Canvas canvas = new Canvas(temp);
int top = 0;
for (Map.Entry<Integer, String> e : layerImages.entrySet()) {
//create the layer bitmap
productIndex = decodeSampledBitmapFromResource(getResources(), e.getValue(), 400, 400);
//add layer to canvas
canvas.drawBitmap(productIndex, 0f, top, null);
}
//convert temp to a BitmapDrawable
Drawable d = new BitmapDrawable(getResources(),temp);
//set my image view to have the flattened image
carBase.setImageDrawable(d);
return temp;
}
The decodeSampledBitmapFromResource come from the Android docs about loading large bitmaps: Loading Large Bitmaps Efficiently You can review the code on that doc to see what I"m doing. I didn't edit the Android code much.
I've been using the Android code just fine to add layers to the FrameLayout but ended up running out of memory when the layers starting getting pretty high in number. This combining method is being used to conserve memory space.
Any ideas why the final bitmap doesn't have any content?
Reference LINK <-------------------------
public Bitmap combineImages(Bitmap c, Bitmap s) { // can add a 3rd parameter 'String loc' if you want to save the new image - left some code to do that at the bottom
Bitmap cs = null;
int width, height = 0;
if(c.getWidth() > s.getWidth()) {
width = c.getWidth() + s.getWidth();
height = c.getHeight();
} else {
width = s.getWidth() + s.getWidth();
height = c.getHeight();
}
cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(cs);
comboImage.drawBitmap(c, 0f, 0f, null);
comboImage.drawBitmap(s, c.getWidth(), 0f, null);
// this is an extra bit I added, just incase you want to save the new image somewhere and then return the location
/*String tmpImg = String.valueOf(System.currentTimeMillis()) + ".png";
OutputStream os = null;
try {
os = new FileOutputStream(loc + tmpImg);
cs.compress(CompressFormat.PNG, 100, os);
} catch(IOException e) {
Log.e("combineImages", "problem combining images", e);
}*/
return cs;
}