Generate scaled version of ImageView drawable - android

I want to generate a scaled version of a drawable coming from an imageView and show it as small icon for a dialog.
I'm using this code but the picture keeps its initial size
Drawable drw = image.getDrawable().mutate().getConstantState().newDrawable();
Drawable drwScal = new ScaleDrawable(drw, 0, 0.5f, 0.5f).getDrawable();
drwScal.setLevel(5000);
new MaterialDialog.Builder(context)
.title(String.format(getResources().getString(R.string.summary)))
.icon(drwScal)
.content(sommaire)
.forceStacking(true)
.show();
what is wrong ?

You can take the content of the ImageView as a Bitmap and scale the bitmap itself like this:
BitmapDrawable drawable = (BitmapDrawable) image.getDrawable();
Bitmap bitmap = drawable.getBitmap();
private static Bitmap scaleBitmap(Bitmap bitmap, float scaleFactor) {
final int sizeX = Math.round(bitmap.getWidth() * scaleFactor);
final int sizeY = Math.round(bitmap.getHeight() * scaleFactor);
return Bitmap.createScaledBitmap(bitmap, sizeX, sizeY, false);
}

Related

Using bitmap to take image from imageview

I'm having a problem using bitmap to take image from imageview... The code for using bitmap to take image by its ID is: (my picture name = test_image)(my imageview = imageView)
Bitmap image;
...
image = BitmapFactory.decodeResource(getResources(), R. drawable.test_image);
But I want it to take the image inside the imageview.Without specifying the image name.
Due to the reason that I want to upload image into the imageview and process the image that is in imageview.
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmap = drawable.getBitmap();
This is how you can get bitmap from any imageview
private Bitmap getImageViewFromBitmap(ImageView v){
Bitmap bm=((BitmapDrawable)v.getDrawable()).getBitmap();
return bm;
}
private Bitmap drawableToBitmap (Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable)drawable).getBitmap();
}
int width = drawable.getIntrinsicWidth();
width = width > 0 ? width : 1;
int height = drawable.getIntrinsicHeight();
height = height > 0 ? height : 1;
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
Call this function as below :
Drawable drawable = imageView.getDrawable();
Bitmap bitmap = drawableToBitmap(drawable);

Two bitmaps in one imageview with different scaletype

Hello I have a simple problem..
I need put two different bitmaps into one imageview. but One bitmaps must be on ImageView.ScaleType.FIT_XY and second on ImageView.ScaleType.FIT_CENTER
I found some methods from internet but all put with same scaletype.
Thanks for advice.
i need in imageview have this.. (image no pageview..)
////////// for explain why I need.
#Override public Object instantiateItem(ViewGroup view, int position) {
ImageView img= new ImageView(view.getContext());
ImageLoader.getInstance().displayImage(listKone.get(pozicia).getCestaObrazok(), img);
//
ImageLoader.getInstance().displayImage(listKone.get(pozicia).getCestaObrazok(), img2);
BitmapDrawable drawable = (BitmapDrawable) img2.getDrawable();
Bitmap bitmap = null;
try {
bitmap = drawable.getBitmap();
} catch (NullPointerException e){
}
while ((drawable==null)||(bitmap==null)) {
ImageLoader.getInstance().displayImage(listKone.get(pozicia).getCestaObrazok(), img2); // Default options will be used
drawable = (BitmapDrawable) img2.getDrawable();
bitmap = drawable.getBitmap();
}
Bitmap blurred = blurRenderScript(act, bitmap, 25);
view.addView(img, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
return img;
}
return img; I need Bitmap blurred and Bitmap Bitmap in one Imageview. But bitmap Blured FIT_XY and bitmap bitmap center. I need get view like in image ↑
use two imageview one over one.
<layer-list>
<item>
<bitmap android:src="#drawable/bitmap1"
android:gravity="fill" />
</item>
<item>
<bitmap android:src="#drawable/bitmap2"
android:gravity="center" />
</item>
</layer-list>
You can use LayerDrawable like this to set two image on on another, then set them in ImageView
I find method which I edited..
public static Bitmap CombineImages(Bitmap background, Bitmap foreground) {
int width = (int) act.getResources().getDimension(R.dimen.imageH);
int height = (int) act.getResources().getDimension(R.dimen.imageH);
Bitmap cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(cs);
background = Bitmap.createScaledBitmap(background, width, height, true);
comboImage.drawBitmap(background, 0, 0, null);
float Fwidth = foreground.getWidth();
float Fheight = foreground.getHeight();
if (Fheight>Fheight){
Fwidth=(height/Fheight) * Fwidth;
Fheight=height;
foreground = Bitmap.createScaledBitmap(foreground,(int) Fwidth,(int) Fheight, true);
}
if (Fheight<=Fheight){
Fheight=(width/Fwidth)*Fheight;
Fwidth=width;
foreground = Bitmap.createScaledBitmap(foreground,(int) Fwidth,(int) Fheight, true);
}
float top = (height-Fheight)/2;
float left = (width-Fwidth)/2;
comboImage.drawBitmap(foreground, left, top, null);
return cs;
}
Have you better solution write. Ad iterim use this solution. But If in future will have more images will be Unneffective.

createBitmap() returns a bitmap without drawn

I want to scale an existing bitmap. So I use Bitmap.createBitmap(Bitmap b, int x, int y, int width, int height, Matrix m, boolean filter) to create a scaled bitmap. If the scale ratio of the Matrix object is less than 1, this method works well. However, if the ratio is equal to or greater than 1, the method returns a bitmap with the width and height i desire but without an image (is transparent). I wonder why and how to solve this.
Bitmap imageBitmap;
imageBitmap = weiboView.getDrawingCache();
Log.d("cosmo", "bitmap generated: "+imageBitmap.getWidth()+" * "+imageBitmap.getHeight());
//Init and configure and load the image view
ImageView imageView = new ImageView(this);
imageView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
imageView.setScaleType(ScaleType.FIT_CENTER);
containerLayout.addView(imageView);
//create a scaled bitmap to assign to the image view
Bitmap scaledImageBitmap = MyBitmapUtils.getBitmapScaledToFitWidth(getWindowManager().getDefaultDisplay().getWidth(), imageBitmap);
Log.d("cosmo", "scaled: "+scaledImageBitmap.getWidth()+" * "+scaledImageBitmap.getHeight());
//Here if I set imageBitmap as the image of imageView it works well
imageView.setImageBitmap(scaledImageBitmap);
Here is MyBitmapUtils.getBitmapScaledToFitWidth:
public static Bitmap getBitmapScaledToFitWidth(int targetWidth, Bitmap bitmap) {
float ratio = (float)targetWidth/(float)bitmap.getWidth();
Log.d("cosmo", "ratio is "+ratio);
//ratio = 0.5f;
Matrix matrix = new Matrix();
matrix.postScale(ratio, ratio);
Bitmap target = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,false);
return target;
}
I have known how did this happen. It's because that the height of the Image is greater than 2048, and in android's system creating a bitmap bigger than 2048*2048 will cause OOM (My logcat didn't report this error, oddly)
Why don't you just use createScaledBitmap?
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, targetWidth, targetHeight, true);
You can supply the targetWidth and targetHeight directly and it should be more reliable than scaling the bitmap yourself with a Matrix.
If you just supply the targetWidth to your method then you have to calculate the targetHeight which would look something like this:
float ratio = (float)targetWidth/(float)bitmap.getWidth();
int targetHeight = (int)((float)bitmap.getHeight * ratio);
And if you put that in your method it would look like this:
public static Bitmap getBitmapScaledToFitWidth(double targetWidth, Bitmap bitmap) {
double bitmapWidth = bitmap.getWidth();
double bitmapHeight = bitmap.getHeight();
double widthRatio = targetWidth / bitmapWidth;
double targetHeight = widthRatio * bitmapHeight;
Bitmap target = Bitmap.createScaledBitmap(bitmap, (int)targetWidth, (int)targetHeight, true);
return target;
}
Also don't forget to recycle() not needed bitmaps as often and as soon as possible. That can prevent you from running into memory problems, for example if you don't need the not scaled bitmap anymore after scaling it you can recycle it directly in your helper method:
public static Bitmap getBitmapScaledToFitWidth(double targetWidth, Bitmap bitmap) {
double bitmapWidth = bitmap.getWidth();
double bitmapHeight = bitmap.getHeight();
double widthRatio = targetWidth / bitmapWidth;
double targetHeight = widthRatio * bitmapHeight;
Bitmap target = Bitmap.createScaledBitmap(bitmap, (int)targetWidth, (int)targetHeight, true);
// Recycle old bitmap to free up memory.
bitmap.recycle();
return target;
}

Create bitmap overlay with some information

I've created a Bitmap [Thumbnail] which is fetched after picking a video from gallery.
Snippet:-
bm= ThumbnailUtils.createVideoThumbnail(currentFileUri.getPath(), MediaStore.Video.Thumbnails.MICRO_KIND);
I'm putting these bitmap in Gallery adapter which is meant from images only, tht's y i'm creating thumbnail of Video and putting there. But
I want to show some difference between image and video in Gallery Strip which can be done by overlaying VideoThumbnail with something like Play Option.
Tried to OverLay my Bitmap with Small Play Icon but it throws NullPointerException on Bitmap.CreateScaledBitmap(..)
Snippet:-
bm= ThumbnailUtils.createVideoThumbnail(currentFileUri.getPath(), MediaStore.Video.Thumbnails.MICRO_KIND);
Bitmap change = null;
Bitmap border = BitmapFactory.decodeResource(getResources(), android.R.drawable.ic_media_play);
int width = bm.getWidth();
int height = bm.getHeight();
change = Bitmap.createScaledBitmap(change, width, height, false);
Canvas canvas = new Canvas(change);
Bitmap scaledBorder = Bitmap.createScaledBitmap(border,width/2,height/2, false);
canvas.drawBitmap(scaledBorder, 0, 0,null);
Adding that newly Overlay Created bitmap on my adapter.
AddIPDActivity.this.data.add(bm);
Created Overlay BitMap with LayerDrawable
Bitmap on which overlay need to be done.
bm = ThumbnailUtils.createVideoThumbnail(currentFileUri.getPath(),MediaStore.Video.Thumbnails.MICRO_KIND);
LayerDrawable applied on Bitmap with custom image on it.
Resources r = getResources();
Drawable[] layers = new Drawable[2];
layers[0] = new BitmapDrawable(bm);
layers[1] = r.getDrawable(android.R.drawable.ic_media_play);
LayerDrawable layerDrawable = new LayerDrawable(layers);
Added Bitmap on Gallery - Adapter.
this.data.add(drawableToBitmap(geSingleDrawable(layerDrawable))); //data is adapter for Gallery.
Converting LayerDrawable into BitMap:-
LayerDrawable -> Drawable -> BitMap
public static Drawable geSingleDrawable(LayerDrawable layerDrawable){
int resourceBitmapHeight = 136, resourceBitmapWidth = 153;
float widthInInches = 0.9f;
int widthInPixels = (int)(widthInInches * SmartConsultant.getApplication().getResources().getDisplayMetrics().densityDpi);
int heightInPixels = widthInPixels * resourceBitmapHeight / resourceBitmapWidth;
int insetLeft = 10, insetTop = 10, insetRight = 10, insetBottom = 10;
layerDrawable.setLayerInset(1, insetLeft, insetTop, insetRight, insetBottom);
Bitmap bitmap = Bitmap.createBitmap(widthInPixels, heightInPixels, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
layerDrawable.setBounds(0, 0, widthInPixels, heightInPixels);
layerDrawable.draw(canvas);
BitmapDrawable bitmapDrawable = new BitmapDrawable(SmartConsultant.getApplication().getResources(), bitmap);
bitmapDrawable.setBounds(0, 0, widthInPixels, heightInPixels);
return bitmapDrawable;
}
public static Bitmap drawableToBitmap (Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable)drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
u r getting NPE because
Bitmap change = null;
change = Bitmap.createScaledBitmap(change, width, height, false);
change is always null. U r passing a null value.So, before passing change as a parameter of createScaledBitmap(parameters) assign a bitmap to change after that call this
change = Bitmap.createScaledBitmap(change, width, height, false);

How to make bitmap transparent?

/**
* #param bitmap
* The source bitmap.
* #param opacity
* a value between 0 (completely transparent) and 255 (completely
* opaque).
* #return The opacity-adjusted bitmap. If the source bitmap is mutable it
* will be adjusted and returned, otherwise a new bitmap is created.
* Source : http://stackoverflow.com/questions/7392062/android-
* semitransparent-bitmap-background-is-black/14858913#14858913
*/
private Bitmap adjustOpacity(Bitmap bitmap, int opacity) {
Bitmap mutableBitmap = bitmap.isMutable() ? bitmap : bitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
int colour = (opacity & 0xFF) << 24;
canvas.drawColor(colour, PorterDuff.Mode.DST_IN);
return mutableBitmap;
}
Using adjustOpacity, I make ImageView's Bitmap be semi-transparent.
Bitmap newBitmap = adjustOpacity(orignalBitmap, 10);
view.setImageBitmap(newBitmap);
view.setBackgroundColor(Color.WHITE);
However, Imageview show more darkent before not white. How do I make a semi-transparent (white background) Imageview with Bitmap?
// Convert transparentColor to be transparent in a Bitmap.
public static Bitmap makeTransparent(Bitmap bit, Color transparentColor) {
int width = bit.getWidth();
int height = bit.getHeight();
Bitmap myBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
int [] allpixels = new int [ myBitmap.getHeight()*myBitmap.getWidth()];
bit.getPixels(allpixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(),myBitmap.getHeight());
myBitmap.setPixels(allpixels, 0, width, 0, 0, width, height);
for(int i =0; i<myBitmap.getHeight()*myBitmap.getWidth();i++){
if( allpixels[i] == transparentColor)
allpixels[i] = Color.alpha(Color.TRANSPARENT);
}
myBitmap.setPixels(allpixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
return myBitmap;
}
The above code will take a Bitmap, and return a Bitmap where every pixel which the color is transparentColor is transparent. This works in API as low as level 8, and I have not tested it in any lower.
I typically use something like Color.RED to make my transparent pixels, because I don't use a lot of RED in my assets, but if I do it's a custom red color.
Making an existing bitmap transparent is too simple.
If you want to make your bitmap transparent before further drawing follow this.
if your bitmap is mBitmap then Just use:-
mBitmap.eraseColor(Color.TRANSPARENT)
Thats it. Good luck !!
Try this. Also note that setAlpha is in 0-255 range
//bmp is your Bitmap object
BitmapDrawable bd = new BitmapDrawable(bmp);
bd.setAlpha(50);
ImageView v = (ImageView) findViewById(R.id.image);
v.setImageDrawable(bd);
Add method
Bitmap bmp; DrawView DrawView;
private static Bitmap makeTransparentBitmap(Bitmap bmp, int alpha) {
Bitmap transBmp = Bitmap.createBitmap(bmp.getWidth(),
bmp.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(transBmp);
final Paint paint = new Paint();
paint.setAlpha(alpha);
canvas.drawBitmap(bmp, 0, 0, paint);
return transBmp;
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.rgb(43,44,45));
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.mouse);
canvas.drawBitmap(bmp, pos_x, pos_y, null);
}
You event:
bmp = makeTransparentBitmap( bmp, 122 );
DrawView.invalidate();
DrawView is
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DrawView = new DrawView(this);
setContentView( DrawView );
}
I found this answer here
try this,
newBitmap.setImageResource(android.R.color.transparent);
#akaya's answer is the right way except that the constructor is deprecated. The new way since API 4 would be to use:
BitmapDrawable drawable = new BitmapDrawable(getResources(), bitmap);
drawable.setAlpha(100);

Categories

Resources