Bitmap create null pointer exception - java

Here is my xml file : Image view im trying to access
<ImageView
android:layout_width="350dip"
android:layout_height="400dip"
android:id="#+id/imgview"
android:background="#drawable/pattern"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
Here is my code.. kindly review the code and let me know where i am doin things wrong i have searched all over the internet just cant try to figure it out how to make bitmap object and draw canvas on image view
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setContentView(new SampleView(this));
}
private static class SampleView extends View {
private ImageView img;
// CONSTRUCTOR
public SampleView(Context context) {
super(context);
setFocusable(true);
img = (ImageView)findViewById(R.id.imgview);
}
#Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
canvas.drawColor(Color.GREEN);
//I keep on getting null pointer exception here
Bitmap b = Bitmap.createBitmap(img.getMeasuredWidth(),img.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
c.drawRect(0, 0, 200, 200, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
paint.setTextSize(40);
paint.setTextScaleX(1.f);
paint.setAlpha(0);
paint.setAntiAlias(true);
c.drawText("Your text", 30, 40, paint);
paint.setColor(Color.RED);
canvas.drawBitmap(b, 10,10, paint);
}
}
}

If you're getting a NullPointerException on that line, it means img is null, which either means findViewById(R.id.imgview); returned null, or onDraw is being executed as part of super(context); (not sure if that's the case).

When width or height you want to have in your bitmap exceeds the size of device then you may get this error. You should use createScaledBitmap. This will help you.

Related

canvas2Draw - how to connect view class to the canvas2

full code I'm new in android studio and I'm having problem with drawing.
Upon execution it does not work
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View eissa=new eissa(this);
setContentView(eissa);
}
}
class eissa extends View {
private Canvas canvas2;
private Bitmap backingbitmap;
public eissa(Context context) {
super(context);
backingbitmap=Bitmap.createBitmap(100,100,Bitmap.Config.ARGB_8888);
canvas2= new Canvas(backingbitmap);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(0,50,100,null);
canvas2.drawCircle(0,50,100,null);
canvas.drawBitmap(backingbitmap,0,0,null);
}
}
2.
There is a problem with the canvas.drawCircle() because there is no Paint argument (last one). The drawCircle doc says : "Paint: The paint used to draw the circle This value cannot be null."
So you can create a Paint in the constructor to pass to the drawCircle methods:
class eissa extends View {
private Canvas canvas2;
private Bitmap backingbitmap;
Paint viewPaint;
public eissa(Context context) {
super(context);
backingbitmap=Bitmap.createBitmap(100,100,Bitmap.Config.ARGB_8888);
canvas2= new Canvas(backingbitmap);
viewPaint = new Paint();
viewPaint.setColor(0xFFFF0000); // set your desired color here context.getColor(R.color....);
viewPaint.setStrokeWidth(4);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(0, 50, 100, viewPaint);
canvas2.drawCircle(0, 50, 100, viewPaint);
canvas.drawBitmap(backingbitmap, 0, 0, null);
}
}
1.
The view's dimensions are not specified anywhere causing the platform to use the default LayoutParams which have the layout_width and layout_height equal to WRAP_CONTENT so the view is not visible. To address ui issues you can use Tools / Layout inspector which can help identify the cause (incorrect dimensions).
Here is a good tutorial about measuring custom views.
The quickest fix would be to specify dimensions using LayoutParams in setContentView:
// replace setContentView() in onCreate() with this
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
setContentView(eissa, lp);

Constantly update function's parameters

I need some help adjusting a function to be constantly updating (<- that may not make sense at first but hopefully a little more explanation will make it clear). This is going to be a long post but please bear with me.
I've got an Activity and a Custom Class. The Activity's Java file only contains a reference to the seekbar that's in it and the OnSeekBarChangeListener. The XML contains said seekbar, and a reference? to the Custom Class (not sure if it's actually called a reference). Here's the code for both:
Java:
public class Painting extends Activity
{
static SeekBar curveBar;
SampleView sampleView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_painting);
curveBar = (SeekBar)findViewById(R.id.curveBar);
sampleView = new SampleView(this);
curveBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (progress >= 50
{
sampleView.updatePath(progress);
}
else if (progress < 50)
{
sampleView.updatePath((-1) * progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
Toast.makeText(Painting.this, "Value: " + curveBar.getProgress(), Toast.LENGTH_SHORT).show();
}
});
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
tools:context="com.example.android.postvu.SampleView">
<com.example.android.postvu.SampleView
android:id="#+id/view"
android:layout_height="300dp"
android:layout_width="match_parent"/>
<SeekBar
android:id="#+id/curveBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/view"
android:layout_alignParentBottom="true"
android:layout_marginStart="40dp"
android:layout_marginEnd="40dp"
android:elevation="50dp"/>
</RelativeLayout>
My Custom Class is what actually draws the canvas with the curve on the top half. In this class I've got 2 constructors:
public SampleView(Context context, AttributeSet attrs)
{
super(context, attrs);
setFocusable(true);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(90);
mPaint.setTypeface(Typeface.SERIF);
mPath = new Path();
makePath(mPath);
mPathPaint = new Paint();
mPathPaint.setAntiAlias(true);
mPathPaint.setColor(Color.rgb(255,0,0));
mPathPaint.setStyle(Paint.Style.STROKE);
}
public SampleView(Context context)
{
super(context);
setFocusable(true);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(90);
mPaint.setTypeface(Typeface.SERIF);
Log.d("LOGCAT", "" + value);
mPath = new Path();
makePath(mPath);
mPathPaint = new Paint();
mPathPaint.setAntiAlias(true);
mPathPaint.setColor(Color.rgb(255,0,0));
mPathPaint.setStyle(Paint.Style.STROKE);
}
AND FINALLY the 2 functions that I'm stuck on. The first is simply being called from the seekbar in the Activity and it's just so that I can get the value of the seekbar at all times while it's being moved.
public void updatePath(int seekbarProgress)
{
value = seekbarProgress * 6;
}
The second function is what draws the curve itself based on a Bezier Curve:
public void makePath(Path p)
{
// p.moveTo(250, -300);
p.moveTo(0,0);
// p.cubicTo(-250, -550, 750, -550, 250, -300);
p.cubicTo(0,-400,600,-400,600,0); //semi-circle?
// p.cubicTo(-600, -400, 600, -400, 0, 0); //as far as the curve probably should allow
// p.cubicTo(0, 0, 0, 0, 620,0); //flat line
}
MY ACTUAL QUESTION
How can I change the makePath function to take the value variable from the updatePath function so that I can make the p.cubicTo look like p.cubicTo(0,-400,600,-400,value,0) considering that I'm calling makePath in both of the constructors?
****EDIT****
The 2 constructors from my Custom Class (and relevant function) now look like this:
public SampleView(Context context, AttributeSet attrs)
{
super(context, attrs);
setFocusable(true);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(90);
mPaint.setTypeface(Typeface.SERIF);
mPath = new Path();
// updatePath(value);
makePath(mPath, value);
mPathPaint = new Paint();
mPathPaint.setAntiAlias(true);
mPathPaint.setColor(Color.rgb(255,0,0));
mPathPaint.setStyle(Paint.Style.STROKE);
}
public SampleView(Context context)
{
super(context);
setFocusable(true);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(90);
mPaint.setTypeface(Typeface.SERIF);
mPath = new Path();
// updatePath(value);
makePath(mPath, value);
Log.d("LOGTAG2", "" + value);
mPathPaint = new Paint();
mPathPaint.setAntiAlias(true);
mPathPaint.setColor(Color.rgb(255,0,0));
mPathPaint.setStyle(Paint.Style.STROKE);
}
public int updatePath(int seekbarProgress)
{
return value = seekbarProgress * 6;
}
public void makePath(Path p, int number)
{
p.moveTo(0,0);
p.cubicTo(0, 0, 0, 0, number,0); //flat line
}
Android Studio is highlighting updatePath and when I hover over it, it tells me Return value of the method is never used. Unless I'm doing something wrong, I am using that value in both constructors where it says makePath(mPath, value);. I'm not sure what else to do at this point because it doesn't make any sense to me. I really want to know 1) how to fix it and 2) what's causing it (why it's telling me that I am not using it (which I think I am)).

How can I correctly use the Canvas class to show an image into an ImageView in this simple Android app?

I am absolulty new in Android and I am doing some experiment with the Canvas object.
I am trying to add it to a Canvas and then show it into a retrieved ImageView (I know that this is not the standard and simplest way to show an image into an ImageView but this is only a simplified experiment for a further more complex thing that I have to do using Canvas).
So I have a star.png (a 32x32 px icon into my /res/drawable/ folder) and I am trying to
This is my activity_main.xml layout configuration file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<ImageView
android:id="#+id/star_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
This layout contain the ImageView having id=star_container that is where I have to draw the image using the Canvas
And this is the MainActivity class that handle this view:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imgView = (ImageView) findViewById(R.id.star_container);
Canvas canvas;
Bitmap star = BitmapFactory.decodeResource(getResources(), R.drawable.star);
Bitmap output = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888);
canvas = new Canvas(output);
canvas.drawBitmap(star, star.getWidth() + 2, 0, null);
imgView.setImageDrawable(new BitmapDrawable(getResources(), output));
}
}
So into the onCreate() method I retrieve the ImageView where the image have to be placed. Then I create a Bitmap object retrieving the star.png image from the resoruces that will be added to the otuput Bitmap using the Canvas.
Finally I set this output Bitmap into the retrieve ImageView.
So I expected that, when the app is running, the previous ImageView contains the star.png image but it does not appear.
I have no error when I execute this app but the only output that I obtain is the textual message defined into the TextView.
Why? What is wrong? What am I missing? How can I modify this code and let it work?
According to the documents:
left: The position of the left side of the bitmap being drawn
The problem is here :
canvas.drawBitmap(star, star.getWidth() + 2, 0, null);
You're using a value for left that is out of bitmap bounds, So nothing is drawn, try this: canvas.drawBitmap(star, 0, 0, null);
Android API provides another method to set Bitmap as drawable directly :
ImageView#setImageBitmap(Bitmap bm)
I think it's a better practice to implement a custom View and explore Canvas capabilities there (in onDraw method)
another way - using rect area:
Canvas canvas;
Bitmap star = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
Bitmap output = Bitmap.createBitmap(star.getWidth(), star.getHeight(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(output);
Rect source = new Rect(0, 0, star.getWidth(), star.getHeight());
canvas.drawBitmap(star, null, source, null);
imgView.setImageBitmap(output);

Widget with custom text support

I have used custom text for widget but i know that widget can't support custom text mean TextView with our TTF file
So i have used below code for support
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
......................
remoteViews.setTextColor(R.id.textViewGuj, settings.getInt(
Const.Mean_Pref_Color_Key,
context.getResources().getColor(R.color.orange)));
remoteViews.setTextViewText(R.id.textViewEng, engWord);
remoteViews.setImageViewBitmap(R.id.textViewGuj,
buildUpdate(meaning));
remoteViews.setOnClickPendingIntent(R.id.LinearLayout01,
pendingIntent1);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
public Bitmap buildUpdate(String time)
{
Bitmap myBitmap = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_4444);
Canvas myCanvas = new Canvas(myBitmap);
Paint paint = new Paint();
Typeface clock = Typeface.createFromAsset(mContext.getAssets(),"fonts/Gujarat.ttf");
paint.setAntiAlias(true);
paint.setSubpixelText(true);
paint.setTypeface(clock);
paint.setStyle(Paint.Style.FILL);
paint.setColor(settings.getInt(
Const.Mean_Pref_Color_Key,
mContext.getResources().getColor(R.color.orange)));
//paint.setColor(Color.WHITE);
paint.setTextSize(20);
paint.setTextAlign(Align.CENTER);
myCanvas.drawText(time, 80, 60, paint);
return myBitmap;
}
and for update ImageView
remoteViews.setImageViewBitmap(R.id.textViewGuj,
buildUpdate(meaning));
Now my problem is that my widget is showing me nothing it goes dark black nothing is shown in widget no any error is generating can any one help me?
I think there is a problem in your below code
remoteViews.setTextColor(R.id.textViewGuj, settings.getInt(
Const.Mean_Pref_Color_Key,
context.getResources().getColor(R.color.orange)));
just remove this line because you are using ImageView and there is no any TextColor Property for ImageView
Hope works fine :)

Initializing Bitmap variable with bitmap drawable from resources is not working - using ANDROID

I use the following code to initialize my bitmap variable:
Bitmap bitmap = ((BitmapDrawable)this.model.gameView.context.getResources().getDrawable(R.drawable.pic1)).getBitmap();
When I try to log the width of that bitmap, the log does not even output anything for that call.
I know it's making it to that line, because I traced the code.
Also, when I try to do canvas.draw for the bitmap, nothing is drawn on the screen.
Everything I draw with rectangles works fine.
My picture resource is a PNG.
Any help is appreciated!
Try something like this for your bitmap class.
public class DrawBitmap extends View
{
Bitmap bitmap;
public DrawBitmap(Context content)
{
super(content);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic1);
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);//whatever color you want, make sure it's not the same as your image
canvas.drawBitmap(bitmap, (canvas.getWidth()), 0, null);
}
}
Main Class
public class Main extends Activity
{
DrawBitmap myView;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myView = new DrawBitmap(this);
setContentView(myView);
}
}
Try using BitmapFactory.decodeResource
Have a look at the answer in this topic:
How to convert a Drawable to a Bitmap?
Just figured it out. It had nothing to do with the method of bitmap loading I used.
It was a logical error on my part. My code accidentally reached a case where my bitmap became null, and it tried to draw the null resource on the canvas.

Categories

Resources