I have been trying to blur an imageview and set the background of the whole layout to the blurred bitmap to no avail. Basically what am trying to achieve is shown in these pictures, where they only blur the imageView and set the expanded blurred image as the layout background.
int color = getDominantColor(bitmap); //get dominant color of the bitmap
//create gradient
GradientDrawable gradient = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
new int[] {0xf5f5f5,color});
gradient.setCornerRadius(0f);
//setbackground of the relativelayout
rl.setBackground(gradient);//rl is relative layout
//getting dominant color of bitmap
public static int getDominantColor(Bitmap bitmap) {
Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, 1, 1, true);
final int color = newBitmap.getPixel(0, 0);
newBitmap.recycle();
return color;
}
I dont want tp set the background as a gradient, but as the blurred result of that image bitmap, just like in the images i've included.
There are many options:
You can enlarge and then downscale the bitmap. What that does is decrease the number of pictures producing something like the effect of blurring. See here if you want to do that: Fast Bitmap Blur For Android SDK. However, it isn't very memory efficient and you may want to change your implementation if it works like this.
Use a pre-made library. There are many libraries, some better than others, allowing you to blur bitmaps. The people who made these libraries have already done the hard job at reducing memory usage and better compatibility. An example is also here: Fast Bitmap Blur For Android SDK
Note: I didn't post any code because part of the solution is libraries or custom classes.
Hope it helps.
Related
I am writing a game program for educational purposes. I'm using the SurfaceView class. The program displays the images on the screen using the Canvas object. The drawable folder contains a png-image. By the name of the picture "bitmapName" I get the Bitmap using this code
int resID = context.getResources().getIdentifier(bitmapName, "drawable", context.getPackageName());
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resID);
I use the drawBitmap() method to draw the resulting Bitmap to the screen. The problem is that the object on which this picture is superimposed is used in the program quite often and the picture should have different shades depending on the logic. The image is now yellow, then green, and other shades.
And there are a LOT of shades. The easiest way to do this is simply to create images of different shades in advance and load them into memory. But uploading a lot of pictures will greatly increase the size of the application, and I would not want this. I tried this in Photoshop. I put a layer on top of the image and filled it with a solid color. Lowered the opacity of this layer. The result is a picture that looks like what I want. Therefore, the question is: how to create a Bitmap from another ready-made Bitmap and some color with transparency.
I need a method to which I send Bitmap, color, transparency level; and get a ready-made Bitmap of a changed shade from it. Can you tell me how can I achieve this result? How to overlay color on Bitmap?
I am using chrisbanes's photoview library for zoomable images. https://github.com/chrisbanes/PhotoView
Image i am trying to load has 2000x2000 resolution.
Simply, I first load the bitmap, then I draw something to the bitmap I loaded. then I load the bitmap to the imageview. I need to manipulate the source image differently for each use, so I need to create a bitmap to create a canvas. But at line where creating bitmaps, in some devices the app throws outOfMemoryException. I check the logs and the original bitmap size is 5250x5250 and creating another bitmap with same size drains a lot of memory i think.
I have tried loading bitmap with BitmapFactory.Options, i used inSampleSize but it degraded the image.
PhotoView imageView;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.test_image);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
Bitmap tempBitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(tempBitmap);
canvas.drawBitmap(bitmap,0,0,null);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4);
//drawing operations, like
//canvas.drawCircle(tempX,tempY,tempRadius,paint);
//canvas.drawLine(firstX,firstY,secondX,secondY,paint);
imageView.setImageDrawable(new BitmapDrawable(getResources(),tempBitmap));
Since i use photoview, the imageview is zoomable and i need the image is well detailed even if fully zoomed but using inSampleSize regrades the image. I want it to be memory efficient and smooth as possible.
You should be able to use Subsampling Scale Image View for the purpose of processing large images without encountering the OutOfMemoryError. As recommended by others, it's not recommend to use large images but this should assist you achieve the functionality you desire.
The view optionally uses subsampling and tiles to support very large images - a low resolution base layer is loaded and as you zoom in, it is overlaid with smaller high resolution tiles for the visible area. This avoids holding too much data in memory. It's ideal for displaying large images while allowing you to zoom in to the high resolution details. You can disable tiling for smaller images and when displaying a bitmap object.
The important thing about this I want to point is: -
Tested up to 20,000x20,000px, though larger images are slower
I have an android project to process images, I have two images, I want to overlay one over another (blending). To combine these two images, it’s a bit simple, using drawing on canvas:
I used this code:
public static Bitmap overlay(Bitmap bottomImg, Bitmap topImg) {
Bitmap bmOverlay = Bitmap.createBitmap(bottomImg.getWidth(),bottomImg.getHeight(),bottomImg.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bottomImg, new Matrix(), null);
canvas.drawBitmap(topImg, 0, 0, null);
return bmOverlay;
}
It works well, but It doesn’t manipulate the transparency of overlaed image. Actually I want the top image to be transparent, in order to see how it matches the bottom one. It’s something to access alpha channel or to do it manually, Can someone help me to do this task.
You can try :
topImg.eraseColor(Color.TRANSPARENT);
This will set all the pixels to transparent.
I am trying to make a composite image from a camera preview and an ImageView that was above it. I have one image that is a transparent png which is set on an imageview like this
ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.one);
I then add it to the framelayout which is already showing my camera preview (inherits SurfaceView) like so:
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(cp); //cp is a reference to a camera preview object
preview.addView(iv);
My imageview's picture is this:
And the screen is something like this (I had to take a the pic from another camera since the DDMS screenshot wasn't showing the preview only the image and a black screen, don't know if that's a relevant though):
Now my task is to take that picture with the imageview. I came up with two approaches, both of which I do not know whether they can or cannot be implemented
Save the picture seperately, keep track of which cover was on the image and then merge someway. Can this be done, and how?
Gain the look of the framelayout in which both Views are residing and save as image
Take screenshot of a specific area, I will onky do this one as a last resort i.e. if this can be done
What I want to know is which one these approaches is possible and how can it be done? or is there a better way to get this done?
Assuming you already have image in form of byte[] data from jpeg callback.
Decode the image into a mutable bitmap:
Bitmap photo = BitmapFactory.decodeByteArray(data, 0, data.length);
photo = photo.copy(photo.getConfig(), true);
Read the overlay:
Bitmap overlay = BitmapFactory.decodeResource(getResources(), R.drawable.one);
Draw overlay on the photo:
Canvas canvas = new Canvas(photo);
canvas.drawBitmap(overlay, new Matrix(), null);
Now, photo should contain your image.
I need to display a very big image (8000x8000 for example) in a view allowing the user to zoom in and out.
I have checked several options for detecting the user touches and transform the image according to that. For example:
How to use Multi-touch in Android
And others using gesture/touch detectors, etc.
The problem is that none of them takes care of the Bitmap size and the posible crashes because the Bitmap doesn't fit in the memory.
So what I'm looking for is how to implement that like the Android's Gallery does. Without lose quality when the image is zoomed in and of course without crashes
Any ideas? Complete, working answers will be bountried with up to 300 points depending on the complexity and quality of the answer
Try showing only a scaled subset of the bitmap and decode as few as possible. I managed something similar to this. These are the code snippets which helped me a lot:
To calculate all values you need (e.g. scale factor, number of pixels etc.) you can use inJustDecodeBounds to get the size of the bitmap without allocating any memory.:
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, opt);
int width = opt.outWidth;
int height = opt.outHeight;
To decode only a subset of a bitmap use this:
Bitmap.createBitmap(
source,
xCoordinateOfFirstPixel,
yCoordinateOfFirstPixel,
xNumberOfPixels,
yNumberOfPixels
);
To create a scaled bitmap:
Bitmap.createScaledBitmap(
source,
dstWidth,
dstHeight,
filter
);
To draw a subset of a bitmap:
Canvas.drawBitmap(
source,
new Rect(
subsetLeft,
subsetTop,
subsetRight,
subsetBottom
),
new Rect(0,0,dstWidth, dstHeight),
paint
);
Edit:
I forget to mentioned this snipplet for creating scaled images. To save memory this is what you want:
BitmapFactory.Options opt = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap scaledBitmap = BitmapFactory.decodeFile(path, opt);
Since inSampleSize must be an integer I used createScaledBitmap to adjust the bitmap a bit more.
http://www.anddev.org/large_image_scrolling_using_low_level_touch_events-t11182.html
Possibly?
the sites down at the moment, so it may not even be relevant to you in the end, but i thought i should post it.
also
" ZOOM CONTROL (Widget) listen to the OnTouch event to handle the panning "
finally:
https://github.com/MikeOrtiz/TouchImageView
^^ might be EXACTLY what your looking for as far as i know 2.0+
failing that, a webview and load the file like that.