RenderScript blur overrides the original Bitmap - java

I am trying to use RenderScript to create a blurred bitmap to set it as a background for a LinearLayout which contains an ImageView. I also want a clear original copy of the bitmap so that I can set it as an image in the ImageView.
Here's my code:
ImageView mainImage;
Bitmap mainBMP, blurredBMP
LinearLayout background;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_work_area);
getImage(); // obtain bitmap from file
mainImage.setImageBitmap(mainBMP); // set the original bitmap in imageview
// create a blurred bitmap drawable and set it as background for linearlayout
BitmapDrawable drawable = new BitmapDrawable(getResources(), blur(mainBMP));
mainBackground.setBackground(drawable);
registerForContextMenu(objectImage);
registerForContextMenu(textArea);
}
private void getImage(){
String filename = getIntent().getStringExtra("image");
try {
FileInputStream is = this.openFileInput(filename);
mainBMP = BitmapFactory.decodeStream(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
#TargetApi(17)
public Bitmap blur(Bitmap image) {
if (null == image) return null;
Bitmap outputBitmap = Bitmap.createBitmap(image);
final RenderScript renderScript = RenderScript.create(this);
Allocation tmpIn = Allocation.createFromBitmap(renderScript, image);
Allocation tmpOut = Allocation.createFromBitmap(renderScript, outputBitmap);
//Intrinsic Gausian blur filter
ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));
theIntrinsic.setRadius(BLUR_RADIUS);
theIntrinsic.setInput(tmpIn);
theIntrinsic.forEach(tmpOut);
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
This is how I want the final result to be:
But this is what I get:
So how do I make two copies of the same bitmap in which one of them is blurred and the other is clear and original?

The problem is with how the output bitmap is being created. You're using a call that gives you an immutable Bitmap object based on an input Bitmap object. Change this line:
Bitmap outputBitmap = Bitmap.createBitmap(image);
to be this:
Bitmap outputBitmap = image.copy(image.getConfig(), true);
That will give you a separate Bitmap object which is a copy of the original and mutable. Right now Renderscript is really modifying the original (though it really should fail because the outputBitmap was immutable.

Related

Cannot resolve method 'getdrawable()

I'm a newbie in programming. I want to build a QR Code Generator that the QR Code can be saved or downloaded.
Here's my code for the generator:
public class GeneratorActivity extends AppCompatActivity {
EditText text;
Button gen_btn;
ImageView image;
String text2Qr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_generator);
text = findViewById(R.id.text);
gen_btn = findViewById(R.id.gen_btn);
image = findViewById(R.id.image);
gen_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
text2Qr = text.getText().toString().trim();
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
try{
BitMatrix bitMatrix = multiFormatWriter.encode(text2Qr, BarcodeFormat.QR_CODE,200,200);
BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
Bitmap bitmap = barcodeEncoder.createBitmap(bitMatrix);
image.setImageBitmap(bitmap);
bitmap = ((BitmapDrawable) ImageView.getdrawable()).getBitmap();
}
catch (WriterException e){
e.printStackTrace();
}
}
});
}
}
I got a error that I cannot resolve method 'getdrawable()
anybody know how to fix this?
Here's the screenshot of the error: screenshot
get the drawable like from imageview like
Drawable myDrawable = imageView.getDrawable();
You can compare it with a drawable resource like
if(iv.getDrawable()==getResources().getDrawable(R.drawable.image1)){
//do work here
}
getDrawable
Return a drawable object associated with a particular resource ID and
styled for the specified theme.
You should pass OBJECT
bitmap = ((BitmapDrawable) image.getDrawable()).getBitmap();
FYI
Drawable drawable = image.getDrawable();
You already have a bitmap and you have set it to imageview. Why do you need this line
bitmap = ((BitmapDrawable) ImageView.getdrawable()).getBitmap();
The error is saying that there is no method called getDrawable() in the ImageView class.
I think you can use it Bitmap bitmap = barcodeEncoder.createBitmap(bitMatrix);directly. may be not need bitmap = ((BitmapDrawable) image.getdrawable()).getBitmap();
You are getting drawable from empty imageview that will return null. for getting bitmap from drawble, try this method.
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
Hope it will help you!!

RecyclerView lags in scrolling

I have a recyclerview with cardview in it. Also having imageview, textview. I am decoding my images using Base64 decoding scheme and displaying images within the cardview.It loads the images but producing the lag effect
onBindViewHolder code
holder.iv_contestant_image.setImageBitmap(new ProcessImage().getBitmage(contestant.getContestant_image()));
ProcessImage code
byte[] decodedString = Base64.decode(strBitmap, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
return decodedByte;
Is something wrong am I doing ?
you can use any image loading libraries. Some of libraries are Picasso Glide Fresco
I do believe decoding process is not instant depending on the size of the bitmap. So, try perform decoding bitmap with AsyncTask
class BitmapWorkerTask extends AsyncTask<Void, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private String base64Img;
public BitmapWorkerTask(ImageView imageView, String base64Img) {
imageViewReference = new WeakReference<ImageView>(imageView);
this.base64Img = base64Img;
}
#Override
protected Bitmap doInBackground(Void... params) {
byte[] decodedString = Base64.decode(base64Img, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
return decodedByte;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
imageViewReference.get().setImageBitmap(bitmap);
}
}
Inside onBindViewHolder
new BitmapWorkerTask(holder.iv_contestant_image, stringBitmap).execute();
you can implement lazy image loading in your recycle view for fix this issue. http://blogs.innovationm.com/lazy-loading-and-memory-management-of-images-in-listview-in-android/

Adding overlay image in ImageView

I am using picasso library to load images from url to ImageView,
Picasso.with(activityContext).load(thumbnailurl)
.into(imageViewReference);
Can I set background image of ImageView (Not the source Image), using Picasso.
You can use callback of picasso.However you can't use setBackgroundResource because it's always takes int as parameter and you will get bitmap in return from picasso.
Picasso.with(getContext()).load(url).into(new Target() {
#Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Drawable d = new BitmapDrawable(getResources(),bitmap);
imageView.setBackground(d);
}
#Override public void onBitmapFailed(Drawable errorDrawable) { }
#Override public void onPrepareLoad(Drawable placeHolderDrawable) { }
});
private Bitmap overlay(Bitmap bitmap1, Bitmap bitmap2) {
Bitmap bmOverlay = Bitmap.createBitmap(bitmap1.getWidth(), bitmap1.getHeight(), bitmap1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bitmap1, new Matrix(), null);
canvas.drawBitmap(bitmap2, new Matrix(), null);
return bmOverlay;
}
if you have to set one image over another the same task i have done by using transparent image from drawable and another one is getting from sdcard,using this code it works,you have to just pass your images bitmap in this method()...

Converting BitmapDrawable into an imageView

I have a particular scenario, I'm very close to finishing! Basically, I've got some decodeBase64 strings in a database that need to be used in a BitmapFactory and then drawn.
public static Bitmap decodeBase64(String input)
{
byte[] decodedByte = Base64.decode(input, 0);
return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
}
Here is my MainActivity.java:
// Initiate Database
DatabaseHandler db = new DatabaseHandler(this); // "this" refer to the context
// Grab current Car for use.
Car cars = db.getCurrentCar();
// Grab String from database and decode to Base64
//ByteConvert.decodeBase64(cars.get_image());
// Create Bitmap object from database source
BitmapFactory(ByteConvert.decodeBase64(cars.get_image());
// Draw image from string
Drawable draw = new BitmapDrawable(getResources(), BITMAPFACTORY GOES HERE);
// Set R.id.DRAWABLE to imageView
My question, is how do I turn this string I'm returning from decodeBase64 into a BitmapFactory and then Draw it?
I have done my best to try and fill out how I think it works.
Thanks
The Base64.decode method is returning a byte array, so you can use BitmapFactory's decodeByteArray method to build your bitmap, and set it on your ImageView.
Ex:
DatabaseHandler db = new DatabaseHandler(this);
Car cars = db.getCurrentCar();
byte[] imageData = Base64.decode(cars.get_image(), 0);
Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length, new BitmapFactory.Options());
ImageView imageView = //find your image view;
imageView.setImageBitmap(bitmap);

Android set bitmap to Imageview

Hi i have a string in Base64 format. I want to convert it ot a bitmap and then display it to an ImageView. This is the code:
ImageView user_image;
Person person_object;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_profile_screen);
// ImageViews
user_image = (ImageView) findViewById(R.id.userImageProfile);
Bundle data = getIntent().getExtras();
person_object = data.getParcelable("person_object");
// getPhoto() function returns a Base64 String
byte[] decodedString = Base64.decode(person_object.getPhoto(), Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
user_image.setImageBitmap(decodedByte);
}
This code get the Base64 String successfully and i do not get any error. But It does not display the image.
What can be the problem?
Thanks
Please try this:
byte[] decodedString = Base64.decode(person_object.getPhoto(),Base64.NO_WRAP);
InputStream inputStream = new ByteArrayInputStream(decodedString);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
user_image.setImageBitmap(bitmap);
//decode base64 string to image
imageBytes = Base64.decode(encodedImage, Base64.DEFAULT);
Bitmap decodedImage = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
image.setImageBitmap(decodedImage);
//setImageBitmap is imp
There is a library named Picasso which can efficiently load images from a URL. It can also load an image from a file.
Examples:
Load URL into ImageView without generating a bitmap:
Picasso.with(context) // Context
.load("http://abc.imgur.com/gxsg.png") // URL or file
.into(imageView); // An ImageView object to show the loaded image
Load URL into ImageView by generating a bitmap:
Picasso.with(this)
.load(artistImageUrl)
.into(new Target() {
#Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
/* Save the bitmap or do something with it here */
// Set it in the ImageView
theView.setImageBitmap(bitmap)
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
There are many more options available in Picasso. Here is the documentation.
this code works with me
ImageView carView = (ImageView) v.findViewById(R.id.car_icon);
byte[] decodedString = Base64.decode(picture, Base64.NO_WRAP);
InputStream input=new ByteArrayInputStream(decodedString);
Bitmap ext_pic = BitmapFactory.decodeStream(input);
carView.setImageBitmap(ext_pic);

Categories