Android--Why I can't see the VIEW directly? - android

I've built a new view named myview including OnDraw section.
And I tried to use setContentView(myview) in Oncreate, however, it failed and showed some error.
Then I use addview function to add this view to my original layout, and setContent(R.layout.main)
Finally I can see the result on the screen.
What was the problem ? Why I can't directly use setContentView(myview) to show the result ?
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myview2=new MyView2(this);
setContentView(R.layout.main2);
RelativeLayout layout= ( RelativeLayout )findViewById(R.id.dashpage);
layout.addView(myview2);
}
class MyView2 extends View{
public MyView2(Context context) {
super(context);
}
Bitmap themometer = BitmapFactory.decodeResource(getResources(),
R.drawable.the);
Matrix matrix2 = new Matrix();
Bitmap themometerbmp = Bitmap.createBitmap(themometer, 0, 0, themometer.getWidth(),
themometer.getHeight(), matrix2, true);
public void onDraw(Canvas canvas2)
{
canvas2.drawBitmap(themometerbmp,90,5,null);
}
}

I don't think setContentView is the problem. You are trying to use a drawable. Try this:
Add a function in MyView2:
public Bitmap getBitmapFromDrawable (Drawable drawable) {
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;
}
Then, instead of
Bitmap themometer = BitmapFactory.decodeResource(getResources(), R.drawable.the);
use
Bitmap themometer = getBitmapFromDrawable(getDrawable(R.drawable.the));

Related

Vectordrawable blurry bitmap on ImageView

I created a custom view that extends ImageView. When I set the vector drawable whose viewport is smaller, I am noticing that image is blurry.
If I just use the ImageView, I am seeing the vector image is sharp as it is suppose to be.
In my custom view I override "setImageDrawable", where I do call super and then get bitmap from the drawable to paint later in onDraw.
Here is how i am converting to bitmap
public Bitmap getBitmapFromDrawable(Drawable drawable) {
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
You need to get view width and height, not the drawable, and use these as the drawable bounds. I assume your view dimension might change over time so this is not a one time task. I would store the drawable in a member field:
private Drawable drawable;
#Override
public void setImageDrawable(Drawable drawable) {
this.drawable = drawable;
this.drawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
// invalidate if needed
}
#Override
protected void onMeasure(int wms, int hms) {
super.onMeasure(wms, hms);
if (drawable != null) drawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
}
Then onDraw, just draw the drawable.
Just do drawable.getIntrinsicWidth()*5(any num.), drawable.getIntrinsicHeight()*5 and pass DisplayMatrices in first parameter, it will increase the quality.
public Bitmap getBitmapFromDrawable(Drawable drawable) {
Bitmap bitmap = Bitmap.createBitmap(context.getResources().getDisplayMetrics(), drawable.getIntrinsicWidth()*5,
drawable.getIntrinsicHeight()*5,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}

cannot seem to get bitmap from view in android

My problem is similar to the one in Android View.getDrawingCache returns null, only null.
My code used to work with the method
private Bitmap getBitmapFromView(View v) {
v.setDrawingCacheEnabled(true);
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false); // clear drawing cache
return b;
}
But today I changed the xml layout file. Since the change I have been getting NullPointerException at the line Bitmap b = Bitmap.createBitmap(v.getDrawingCache()). So I tried changing the method getBitmapFromView to
public static Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap(v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
return b;
}
But that didn't help. I get the null in the very first line.
The situation is this: I am trying to convert the view into a bitmap. But I am doing this without first displaying the view on screen. Again, this all used to work until I changed the content of the xml layout file. The change was not even that big. I just moved stuff around and removed -- yes removed -- some of the subviews.
In any case, I know for certain there is no problem with my layout file because I can display it on screen if I want; which I have done as part of troubleshooting.
Someone suggested using a handler to call getDrawingCache(). If that's the answer, how would I write that code?
UPDATE
View view = activity.getLayoutInflater().inflate(R.layout.my_view, null, false);
findViewsByIds(view);//where I inflate subviews and add content to them.
Execute createBitmapFromView when the view is measured.
public static void executeWhenViewMeasured(final View view, final Runnable runnable) {
if(view.getMeasuredHeight() == 0 || view.getMeasuredWidth() == 0){
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
runnable.run();
removeGlobalOnLayoutListener(view, this);
}
});
} else {
runnable.run();
}
}
public static Bitmap createBitmapFromView(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static void removeGlobalOnLayoutListener(View view,
ViewTreeObserver.OnGlobalLayoutListener listener) {
try {
view.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
} catch (NoSuchMethodError e) {
view.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
}
}
executeWhenViewMeasured(view, new Runnable() {
#Override
public void run() {
Bitmap bitmap = createBitmapFromView(view);
}
});
Since you are not showing the view it's easier to just draw the view on a canvas.
You are already trying to do that but I would merge both methods into one without using drawing cache.
private Bitmap getBitmapFromView(View v) {
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredWidth());
Bitmap b = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredWidth(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
Also check that MeasureSpec.UNSPECIFIED may not work well without the view in layout so you may need to specify a width and height.

Saving a canvas in Android does not work every time

I'm having this code:
public void saveimage() {
Bitmap bitmap = Bitmap.createBitmap(colorGFX.getWidth(),
colorGFX.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
canvas = colorGFX.canvas;
canvas.setBitmap(bitmap);
saveBitmap(bitmap);
}
colorGFX object extends a SurfaceView.
saveBitmap actually writes the image on the file.
The problem is that most of the times a WHITE image is saved, other times the correct image is saved.
Did I missed something, or why does the image saves only let's say 1/5 of the times?
This worked for me:
Bitmap bitmap = Bitmap.createBitmap(colorGFX.getWidth(),
colorGFX.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(colorGFX.bitmap, 0f, 0f, null);
canvas.drawBitmap(colorGFX.pictureBitmap, 0f, 0f, null);
saveBitmap(bitmap);
Try this:
public void saveimage() {
Bitmap bitmap = Bitmap.createBitmap(colorGFX.getWidth(),
colorGFX.getHeight(), Bitmap.Config.ARGB_8888);
colorGFX.draw(new Canvas(bitmap))
saveBitmap(bitmap);
}

Draw a line on ImageView set by Picasso

I am trying to figure out how to simply draw a line on an image that is being set in Picasso. I found that if I simply set the image, given a URI, with Picasso and try to draw paint to it using the following:
canvas = new Canvas(bitmap);
image.draw(canvas);
topEdge = new Paint();
topEdge.setColor(context.getResources().getColor(R.color.blue));
topEdge.setStrokeWidth(5);
canvas.drawLine(c1.getX(), c1.getY(), c2.getX(), c2.getY(), topEdge);
Then I get a crash saying that the bitmap needs to be mutable first. So I added this above that code:
Bitmap workingBitmap = ((BitmapDrawable) image.getDrawable()).getBitmap();
Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
And then create the canvas with new Canvas(mutableBitmap) instead. This removed the crash, however nothing is being drawn. I believe this is because my Picasso is setting the image before, so now I need to reset Picasso with this new mutable bitmap. The problem is this code is in the onSuccess() callback for Picasso. What can I do to allow Paint to be drawn on an image through Picasso?
just follow the steps below:
Write your own class extends the class Transformation like below:
class DrawLineTransformation implements Transformation {
#Override
public String key() {
// TODO Auto-generated method stub
return "drawline";
}
#Override
public Bitmap transform(Bitmap bitmap) {
// TODO Auto-generated method stub
synchronized (DrawLineTransformation.class) {
if(bitmap == null) {
return null;
}
Bitmap resultBitmap = bitmap.copy(bitmap.getConfig(), true);
Canvas canvas = new Canvas(resultBitmap);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
canvas.drawLine(0, resultBitmap.getHeight()/2, resultBitmap.getWidth(), resultBitmap.getHeight()/2, paint);
bitmap.recycle();
return resultBitmap;
}
}
}
2、Add the Transformation to RequestCreator created with Picasso.load() function like below:
Picasso picasso = Picasso.with(getApplicationContext());
DrawLineTransformation myTransformation = new DrawLineTransformation();
picasso.load("http://www.baidu.com/img/bdlogo.png").transform(myTransformation).into(imageview);
That's all steps you need to do , just enjoy!

set bitmap which was created from RelativeLayout to imageView

I have RelativeLayout and I want to convert it to the Bitmap like this:
public static Bitmap getBitmapFromView(View view) {
if (view != null)
{ Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable =view.getBackground();
if (bgDrawable!=null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
view.draw(canvas);
return returnedBitmap;
}
else
return null;
}
then I create RelativeLayout cView in the onCreate() method dynamically and set it to the ImageView like this:
dialer = (ImageView) findViewById(R.id.imageView_ring);
dialer.setImageBitmap(getBitmapFromView(cView));
and get error:
05-20 13:48:27.509: E/AndroidRuntime(28367):
java.lang.RuntimeException: Unable to start activity
ComponentInfo{ru.biovamp.widget/ru.biovamp.widget.TestCircleAct}:
java.lang.IllegalArgumentException: width and height must be > 0
I also tried to add bitmap to the ImageView from the onStart() method, but got the same result. What solution can I use?
I've solved my issue like this:
public Bitmap getBitmapFromView() {
this.measure(MeasureSpec.makeMeasureSpec(createNewRelativeLayoutParams().width, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(createNewRelativeLayoutParams().height, MeasureSpec.UNSPECIFIED));
this.layout(0, 0, this.getMeasuredWidth(), this.getMeasuredHeight());
Bitmap returnedBitmap = Bitmap.createBitmap(this.getMeasuredWidth(), this.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(returnedBitmap);
this.draw(c);
return returnedBitmap;
}
so solution is that we should to call measure() and layout() methods before drawing it.
oficial explaniton

Categories

Resources