I am trying to hide a part of an image so that the user does not see it. Initially I copied the Bitmap pixels on another Bitmap, without copying only the pixels that I needed and making the second bitmap the correct size at creation. That worked, but I have many large images and that results in OOMs unfortunately. So instead of doing that I thought on using a ClipDrawable to draw the image, and making the pixels that I don't need invisible.
The code is as follows
ClipDrawable clipDrawable = new ClipDrawable(new BitmapDrawable(resources, bitmap), gravity, orientation);
clipDrawable.setLevel(level);
// Cannot use as the imageview source. Must use background or else we don't get anything on the screen.
picture.setBackground(clipDrawable);
// This is super important. Do not modify this! Without it you will not get the fullscreen image working and the ImageView will be deleted
// from the parent layout.
picture.setImageResource(android.R.color.transparent);
The idea is that I calculate the level based on the image size so that I hide the pixels that I don't need. And it's working. Except I don't understand why I need to use
picture.setBackground(clipDrawable);
picture.setImageResource(android.R.color.transparent);
instead of the more normal:
picture.setImageDrawable(clipDrawable);
If I do the second more normal example then I don't get anything in the ImageView, but if I set it as a background and put a transparent image over it, then it works. Since I want to further manipulate the ImageView using a zooming class that needs the picture set as the src and not as background, I cannot have both, either I get the ClipDrawable showing or I get to have zoom on the image.
Any help would be appreciated!
picture.setImageDrawable(new
ClipDrawable(new BitmapDrawable(resources, bitmap), gravity, orientation
));
ClipDrawable clipDrawable = (ClipDrawable) picture.getDrawable();
clipDrawable.setLevel(level);
Related
I want to dispaly pixelart in an ImageView but it keeps getting blurry.
I tried it like explained in this post (and some others) and I tried it with the function createScaledBitmap like you can see in the code. But it still gets blurry.
What else can I do to show my PixelArt correctly?
var bitmap = Bitmap.createScaledBitmap(fu, 120, 120, false)
var drawable = BitmapDrawable(context.resources, bitmap)
drawable.setAntiAlias(false)
drawable.setFilterBitmap(false)
myImageView.setImageDrawable(drawable )
(The Imageview is inside a RecyclerView but I don't think that that is important for my problem.)
You're scaling the image up before disabling the filtering, so it still looks filtered. It also wastes memory to enlarge a small sprite into a large bitmap.
You don't need to mess with manual scaling like that. You can set the drawable on you ImageView (either assign it in your XML layout or call setImageResource on it). Then set isFilterBitmap to false on its drawable.
myImageView.setImageResource(R.drawable.mySprite) // if not already set in XML
myImageView.drawable?.isFilterBitmap = false
Linked questions
The below questions couldn't finally solve my problem, described below.
Android: Is it possible to repeat an (SVG!) drawable inside an ImageView?
Android: Keep ratio for a full-width and undefined height ImageView in a ConstraintLayout?
Showing a full-width ImageView containing a SVG distorts it
Context
I use a ConstraintLayout. My aim is to show an SVG image which contains a button:
Its width is 100% the screen's width - it must be repeated
Its height is defined to be the space between the bottom side of a widget and the bottom side of the button - it must be repeated
The problem
Each time I tried to show this image, either the drawable was badly scaled, badly cropped or blurred.
An exemple is:
It should look like this:
Many tests
I have tried to use an ImageView with the attribute src: I used every scale type, with and without the attribute that allows to set a custom ratio
I have tried to use an ImageView with a background instead of src
I have tried to use a RelativeLayout with a background drawable file that is repeated: so I didn't use an SVG image but its JPEG version, and even this way has resulted in bad results
Nota for 3.: I'd really want to use an SVG image instead of a bitmap one, because it will be resolutions-compliant.
My question
So, given all these explanations (cf.: part Context) and given the above illustrations, how would you proceed to show this image?
use java code
ColorDrawable colorDrawable = new ColorDrawable(Color.parseColor("#888888")); // bg color
Drawable vDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_vector_star); // vector drawable
if (vDrawable != null) {
Bitmap bitmap = Bitmap.createBitmap(vDrawable.getIntrinsicWidth(), vDrawable.getIntrinsicHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
vDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
vDrawable.draw(canvas);
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
bitmapDrawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); // set repeat
LayerDrawable drawable = new LayerDrawable(new Drawable[]{colorDrawable, bitmapDrawable});
findViewById(R.id.frameLayout).setBackground(drawable);
}
The CircularImageView, https://github.com/Pkmmte/CircularImageView, works great when setting an image bitmap like so...
circularImageView.setImageBitmap(bitmap);
However, there are times where I just want to set a solid color instead of a bitmap. If I do something like this,
circularImageView.setBackgroundResource(R.color.blue);
The color of the view is set but the image is never made circular, so it fill the entire rectangular view. I'm assuming the getDrawable() is returning null so it can't actually manipulate the view. Anyone ran into this problem or any suggestions on what to do?
Edit:
I can do this but it seems a bit flimsy:
Bitmap image = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888);
image.eraseColor(android.graphics.Color.GREEN);
circularImageView.setImageBitmap(image);
You should call circularImageView.setImageResource(R.color.blue) instead.
The code you wrote sets the background of the view, not the content image. Looking at the code on github, this view will only clip the content image to the circle--it has no effect on the background at all.
Give a try for ColorDrawable;
int decode = Integer.decode("FF6666");
ColorDrawable colorDrawable = new ColorDrawable(decode);
How to change TRANSPARENT part of image set in imageview with another image?
Below is the main image, there is TRANSPARENT portion(here looks white), i want to set another image withing that portion of image.
any idea how to do it?
Question:
How to find TRANSPARENT portion starting point LEFT(x,y), RIGHT (x,y), BOTTOM LEFT (x,y), BOTTOM RIGHT(x,y) ? for image replacement.
How to process bitmap in runtime to add another image to make changes in imageview?
I've tried this to find transparent part of image.
You have a bitmap (B1) and there is only one rectangle transparent zone somewhere. And you want to place another bitmap (B2) inside it.
use monte-carlo method to find any transparent pixel on B1. You know
it's coordinates now.
go [left/right/top/bottom] from transparent pixel and find
first solid pixel. Now you know transparent rectangle coorditates.
There are several ways to put something inside transparent area. You can:
place second imageview (with B2) under the first one (with B1). Set B2 padding inside imageview accordingly transparent zone coordinates.
create new image from B1 and B2 and set it to imageview.
do it some other way...
try this example in this crop image with transparent part it will use full for you.
https://github.com/ketanpatel25/Image-Cropping-In-Transparent-Area
I am trying to draw multiple ImageViews inside a single LinearLayout.
All the ImageViews need to have a single bitmap.
The ImageViews will only vary in size.
The single bitmap will not be resized.
The simple way is to create one Bitmap per ImageView. But, this runs out of memory quickly.
final Bitmap placeholderBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
final Canvas canvas = new Canvas(placeholderBitmap);
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.placeholder_image), 0, 0, null);
imageView.setImageBitmap(placeholderBitmap);
linearLayout.addView(imageView);
I also tried setting the max and min height and width, no effect. The images remain the same size.
imageView.setImageResource(R.drawable.ic_no_image);
imageView.setMaxHeight(imageViewInfo.height);
imageView.setMaxWidth(imageViewInfo.width);
I believe working with Drawables is the right "Android" way to do it, but I can't find a way to dynamically create a Drawable with the right side and layering the shared bitmap into it.
Just use one Bitmap -- as you say they will all use the same Bitmap, so no duplication is necessary.
If you want the ImageViews to have different sizes and have the Bitmap scale itself to the size of the ImageView then use the setScaleType or android:scaleType attribute to set the scaling of the ImageView. For instance FIT_START maintains the aspect ratio of your image and tries to fill the ImageView starting from the top-left corner.
I don't see any need to create a Drawable, though if you need to you can just create one from a Bitmap using:
Drawable d = new BitmapDrawable(bitmap);
ImageView actually does this automatically when you call setImageBitmap(...).
ImageView will always resize the bitmap to it need proportions.
If you want to save memory, resize the bitmaps manually and set them into the ImageViews this should stop the ImageView from resizing it internally - to make sure, you can set the layout_width and layout_hieght of the image view to 'wrap_content'.
I think may be looking for a ClipDrawable.
You would set the android:drawable property of the clip XML to your bitmap
That or you can do it with the Java code also given in the example