this is my class.. ı want to use it in my simple game's GameEngine.. but ı didn't understand the problem here.. it doesn't work..
public class Droid {
private Bitmap bitmap;
private int x;
private int y;
private boolean touched;
private Speed speed;
private Paint paint;
public Droid(Resources resources, Bitmap bitmap, int x, int y)
{
this.bitmap = bitmap;
this.x = x;
this.y = y;
// create droid and load bitmap
bitmap = BitmapFactory.decodeResource(resources,
R.drawable.droid_1);
}
public void draw(Canvas canvas)
{
canvas.drawBitmap(bitmap, x - bitmap.getWidth() / 2,
y- bitmap.getHeight() / 2, paint);
}
}
when ı run code, ı see a nullpointerexception at draw() method... how can ı solve this? thanks for help...
MainActivity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
MyView mv = new MyView(this,bmp,100,100);
// pass the bitmap and x and y co-ordinates to the constructor of Myview
setContentView(mv); // set the content to your activity
}
}
Custom view class
public class MyView extends View{ // should extend view
Context c;
private Bitmap bitmap;
private int x;
private int y;
private Paint paint;
public MyView(Context context,Bitmap bmp, int i, int j) {
super(context);
// TODO Auto-generated constructor stub
this.c=context;
this.bitmap=bmp;
this.x=i;
this.y=j;
paint= new Paint();
}
#Override
public void draw(Canvas canvas) // override view on draw and draw the bitmap
{
canvas.drawBitmap(bitmap, x - bitmap.getWidth() / 2,
y- bitmap.getHeight() / 2, paint); // instead of paint you can have null
}
}
// ı hope, ı solved this problem.. finally.. :)
public class Droid {
private Bitmap bitmap;
private int x;
private int y;
private boolean touched;
private Speed speed;
private Paint paint;
public Droid(Resources resources, Bitmap bitmap, int x, int y)
{
paint= new Paint();
// this.bitmap = bitmap; // delete this part, it will work.. :)))
this.x = x;
this.y = y;
// create droid and load bitmap
bitmap = BitmapFactory.decodeResource(resources,
R.drawable.droid_1);
}
public void draw(Canvas canvas)
{
canvas.drawBitmap(bitmap, x - bitmap.getWidth() / 2,
y- bitmap.getHeight() / 2, paint);
}
}
Related
I want to something like to map. I have class, where I'm using ScaleGestureDetector and my bitmap is centered, but after zoom, this bitmap isn't centered. I have coordinates, and I want to implement my vision to android. My object should be centered and I want to be able to zooming and moving screen around this object, this is just all. I have x and y, for example x=14500 and y=50000 and this is always center and I can zoom and slide this "map". I will put another point, objects, but I dream about this code.
Thanks for any help
public class GPS extends ActionBarActivity {
Button btnShowLocation;
GPSTracker gps;
TextView textView;
public void clickOnButton(View v) {
setContentView(new ZoomableView(this));
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gps);
btnShowLocation = (Button) findViewById(R.id.button);
}
public class ZoomableView extends View {
private Drawable image;
private float scaleFactor = 1.0f;
private ScaleGestureDetector scaleGestureDetector;
Bitmap bitmap;
private int mWidth;
private int mHeight;
private float mAngle;
public ZoomableView (Context context) {
super(context);
image = context.getResources().getDrawable(R.drawable.ic_launcher);
setFocusable(true);
image.setBounds(0, 0, image.getIntrinsicWidth(),
image.getIntrinsicHeight());
scaleGestureDetector = new ScaleGestureDetector(context,
new ScaleListener());
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
}
#Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
mWidth = View.MeasureSpec.getSize(widthMeasureSpec);
mHeight = View.MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(mWidth, mHeight);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Set the image bounderies
canvas.save();
canvas.scale(scaleFactor, scaleFactor);
image.draw(canvas);
int cx = (mWidth - bitmap.getWidth()) >> 1;
int cy = (mHeight - bitmap.getHeight()) >> 1;
if (mAngle > 0) {
canvas.rotate(mAngle, mWidth >> 1, mHeight >> 1);
}
canvas.drawBitmap(bitmap, cx, cy, null);
canvas.drawBitmap(bitmap, 100, 10000, null);
canvas.restore();
}
private class ScaleListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScale(ScaleGestureDetector detector) {
scaleFactor *= detector.getScaleFactor();
scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 5.0f));
invalidate();
return true;
}
}
So I have this 9png :
And I have this image :
I need to achieve something like this:
This is the closest I can get to it:
This is how I tried to do it:
public class CustomView extends ImageView {
private Bitmap mImage;
private Bitmap mMask;
private int mPosX = 0;
private int mPosY = 0;
private final Paint maskPaint;
private final Paint imagePaint;
public CustomView(Context context) {
super(context);
maskPaint = new Paint();
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
imagePaint = new Paint();
imagePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
mImage = BitmapFactory.decodeResource(context.getResources(), R.drawable.dummy_video);
mMask = BitmapFactory.decodeResource(context.getResources(), R.drawable.friend_bubble);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.drawBitmap(mMask, 0, 0, maskPaint);
canvas.drawBitmap(mImage, mPosX, mPosY, imagePaint);
canvas.restore();
}
}
My guess is that the 9png just keeps on drawing and doesn't know when to stop.
Can anyone help? :)
Requirement is to:
Req 1 : Fetch images from url
R2: save them in cache
R3: make ImageView rounded not the image
So for R1 & R2 I found a library:
http://loopj.com/android-smart-image-view/
For R3 I've done a lot of R&D , & everything I found converts the image not the ImageView. This is what I've searched:
Mask ImageView with round corner background
How to make an ImageView with rounded corners?
https://github.com/vinc3m1/RoundedImageView
https://github.com/lopspower/CircularImageView
I know it's possible to use the ImageView bitmap & get the image rounded but with the specific library I want to use that isn't possible(maybe possible with very complex threading).
So please help me to get the ImageView rounded not the image.
so this is the minimalistic version:
class RoundImageView extends ImageView {
private static final int RADIUS = 32;
private Paint mPaint;
private Paint mSrcIn;
private RectF mRect;
public RoundImageView(Context context) {
super(context);
// setBackgroundColor(0xffffffff);
mSrcIn = new Paint();
mSrcIn.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mRect = new RectF();
}
#Override
public void onDraw(Canvas canvas) {
Drawable dr = getDrawable();
if (dr != null) {
mRect.set(dr.getBounds());
getImageMatrix().mapRect(mRect);
mRect.offset(getPaddingLeft(), getPaddingTop());
int rtc = canvas.saveLayer(mRect, null, Canvas.ALL_SAVE_FLAG);
// draw DST
canvas.drawRoundRect(mRect, RADIUS, RADIUS, mPaint);
canvas.saveLayer(mRect, mSrcIn, Canvas.ALL_SAVE_FLAG);
// draw SRC
super.onDraw(canvas);
canvas.restoreToCount(rtc);
}
}
}
or use even shorter one when hardware acceleration is not used and you can use Canvas.clipPath:
class RoundImageViewClipped extends ImageView {
private static final int RADIUS = 32;
private RectF mRect;
private Path mClip;
public RoundImageViewClipped(Context context) {
super(context);
// setBackgroundColor(0xffffffff);
mRect = new RectF();
mClip = new Path();
}
#Override
public void onDraw(Canvas canvas) {
Drawable dr = getDrawable();
if (dr != null) {
mRect.set(dr.getBounds());
getImageMatrix().mapRect(mRect);
mRect.offset(getPaddingLeft(), getPaddingTop());
mClip.reset();
mClip.addRoundRect(mRect, RADIUS, RADIUS, Direction.CCW);
canvas.clipPath(mClip);
super.onDraw(canvas);
}
}
}
I'm pretty sure you can't "make the ImageView round," since all Views are actually rectangular, so what you're going to have to do is fake it.
Use a method like this to cut a circle from the image:
public Bitmap getRoundedBitmap(Bitmap scaleBitmapImage) {
int targetRadius = scaleBitmapImage.getWidth();
if(targetRadius > scaleBitmapImage.getHeight()) targetRadius = scaleBitmapImage.getHeight();
Bitmap targetBitmap = Bitmap.createBitmap(targetRadius, targetRadius, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addCircle(((float) scaleBitmapImage.getWidth() - 1) / 2, ((float) scaleBitmapImage.getHeight() - 1) / 2, (Math.min(((float) scaleBitmapImage.getWidth()), ((float) scaleBitmapImage.getHeight())) / 2), Path.Direction.CCW);
canvas.clipPath(path);
Bitmap sourceBitmap = scaleBitmapImage;
canvas.drawBitmap(sourceBitmap, new Rect(0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight()), new Rect(0, 0, scaleBitmapImage.getWidth(), scaleBitmapImage.getHeight()), null);
return targetBitmap;
}
Since the clipped part is transparent, it will appear as if the actual View is a circle. Also make sure that the bounds of the View are squared (or that adjustViewBounds="true") else you may get visual distortions in terms of width or height.
Pretty sure that's as close to a "rounded View" as you can actually get.
How about the solution give by Romain Guy to use a custom Drawable. You're ImageView will not be round and your source image will be untouched.
class StreamDrawable extends Drawable {
private final float mCornerRadius;
private final RectF mRect = new RectF();
private final BitmapShader mBitmapShader;
private final Paint mPaint;
private final int mMargin;
StreamDrawable(Bitmap bitmap, float cornerRadius, int margin) {
mCornerRadius = cornerRadius;
mBitmapShader = new BitmapShader(bitmap,
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(mBitmapShader);
mMargin = margin;
}
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRect.set(mMargin, mMargin, bounds.width() - mMargin, bounds.height() - mMargin);
}
#Override
public void draw(Canvas canvas) {
canvas.drawRoundRect(mRect, mCornerRadius, mCornerRadius, mPaint);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
}
You can add rounded corners in a android view with the GradientDrawable.
So ,
GradientDrawable gd = new GradientDrawable();
gd.setColor(Color.TRANSPARENT);
gd.setCornerRadius(15f);
gd.setStroke(1f,Color.BLACK);
yourImageView.setBackground(gd);
SmartImageView extends from ImageView .. so you just have to extend from SmartImageView
Here is a working solution (based on pskink code & smartImageView lib )
Create a new Class
public class RoundedCornersSmartImageView extends SmartImageView{
private int RADIUS = 0;
private RectF mRect;
private Path mClip;
public RoundedCornersSmartImageView(Context context) {
super(context);
init();
}
public RoundedCornersSmartImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundedCornersSmartImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
#Override
public void onDraw(Canvas canvas) {
Drawable dr = getDrawable();
if (dr != null) {
mRect.set(dr.getBounds());
getImageMatrix().mapRect(mRect);
mRect.offset(getPaddingLeft(), getPaddingTop());
mClip.reset();
mClip.addRoundRect(mRect, RADIUS, RADIUS, Path.Direction.CCW);
canvas.clipPath(mClip);
super.onDraw(canvas);
}
}
public void setRadius(int radius){
this.RADIUS = radius;
}
private void init(){
mRect = new RectF();
mClip = new Path();
}
}
USAGE
in your layout file your SmartimageView should look like this
<your.package.path.RoundedCornersSmartImageView
android:id="#+id/list_image"
android:layout_width="60dip"
android:layout_height="60dip"
android:src="#drawable/profile_anonyme_thumb"/>
..and init the view in your code this way
RoundedCornersSmartImageView thumb_image=(RoundedCornersSmartImageView) findViewById(R.id.list_image);
thumb_image.setRadius(4);
//SmartImageView methode
thumb_image.setImageUrl(bla.MY_THUMB_URL));
Edit your radius for a round image ..
I have been developing the application for drawing, and there is the code:
public class PainterView extends View implements DrawingListener {
private GestureDetector detector;
private Context context;
private Painter painter;
private Bitmap background;
private Bitmap bitmap;
private Paint bitmapPaint;
private Path path;
private Paint paint;
private float x;
private float y;
public PainterView(Context context, Painter painter) {
super(context);
this.context = context;
this.painter = painter;
detector = new GestureDetector(context, new GestureListener());
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
if (bitmap != null) {
canvas.drawBitmap(background, 0, 0, bitmapPaint);
canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
canvas.drawPath(path, paint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
detector.onTouchEvent(event);
x = event.getX();
y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
painter.touchStart(x, y);
break;
case MotionEvent.ACTION_MOVE:
painter.touchMove(x, y);
break;
case MotionEvent.ACTION_UP:
painter.touchUp();
break;
}
return true;
}
#Override
public void onPictureUpdate(Bitmap background, Bitmap bitmap, Paint bitmapPaint, Path path,
Paint paint) {
this.background=background;
this.bitmap = bitmap;
this.bitmapPaint = bitmapPaint;
this.path = path;
this.paint = paint;
invalidate();
}
public void setPainter(Painter painter) {
this.painter = painter;
}
So, the background bitmap is image (ruled paper), and I need to know how can I emulate the eraser in order to allow to user erase his notes?
you could do something like this:
public class Eraser
{
public void erase(int locX, int locY, int brushsize)
{
for(int x = locX - brushsize;x < locX + brushsize;x++)
{
for(int y = locY - brushsize;y < locY + brushsize;y++)
{
map.setPixle(x,y,Color.white);
}
}
}
private Bitmap map;
}
This is a square eraser, I'm sure you could figure out a way to make it a circle if you really wanted to. I hope his helped!
I try to erase parts of a bitmap in my Android application by using Porter-Duff Xfermodes.
I have a green background which is overlayed by a blue bitmap. When I touch the screen a "hole" in the overlaying bitmap is supposed to be created making the green background visible. Instead of a hole my current code produces a black dot.
Below is my code. Any ideas, what I am doing wrong here?
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(new DrawView(this));
}
public class DrawView extends View implements OnTouchListener {
private int x = 0;
private int y = 0;
Bitmap bitmap;
Canvas bitmapCanvas;
private final Paint paint = new Paint();
private final Paint eraserPaint = new Paint();
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
// Set background
this.setBackgroundColor(Color.GREEN);
// Set bitmap
bitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.RGB_565);
bitmapCanvas = new Canvas();
bitmapCanvas.setBitmap(bitmap);
bitmapCanvas.drawColor(Color.BLUE);
// Set eraser paint properties
eraserPaint.setAlpha(0);
eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
eraserPaint.setAntiAlias(true);
}
#Override
public void onDraw(Canvas canvas) {
bitmapCanvas.drawColor(Color.BLUE);
bitmapCanvas.drawCircle(x, y, 10, eraserPaint);
canvas.drawBitmap(bitmap, 0, 0, paint);
}
public boolean onTouch(View view, MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
invalidate();
return true;
}
}
Here is working code... may help somebody
public class ImageDemo extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new Panel(this));
}
class Panel extends View {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mPaint;
Bitmap bitmap;
Canvas pcanvas;
int x = 0;
int y =0;
int r =0;
public Panel(Context context) {
super(context);
Log.v("Panel", ">>>>>>");
setFocusable(true);
setBackgroundColor(Color.GREEN);
// setting paint
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setAntiAlias(true);
// getting image from resources
Resources r = this.getContext().getResources();
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.mickey);
// converting image bitmap into mutable bitmap
bitmap = bm.createBitmap(295, 260, Config.ARGB_8888);
pcanvas = new Canvas();
pcanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
pcanvas.drawBitmap(bm, 0, 0, null);
}
#Override
protected void onDraw(Canvas canvas) {
// draw a circle that is erasing bitmap
pcanvas.drawCircle(x, y, r, mPaint);
canvas.drawBitmap(bitmap, 0, 0,null);
super.onDraw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// set parameter to draw circle on touch event
x = (int) event.getX();
y = (int) event.getY();
r =20;
// At last invalidate canvas
invalidate();
return true;
}
}
}
First thought, I'm not sure if setting alpha to 0 on your erase paint object is a good idea. That might make the whole thing ineffective.
Also, you should always use Bitmap.Config.ARGB_8888 if you're dealing with alphas.
If you're having trouble with the PorterDuff stuff, though, I would suggest simplifying your approach to ONLY do that (temporarily). That will help you narrow down the part which isn't working. Comment out everything to do with touch and view updates.
Then you can single out what part of the drawing isn't working right. Set up your constructor like this:
DrawView()
{
/* Create the background green bitmap */
...
/* Create foreground transparent bitmap */
...
/* Draw a blue circle on the foreground bitmap */
...
/* Apply the foreground to the background bitmap
using a PorterDuff method */
...
}
onDraw()
{
/* Simply draw the background bitmap */
...
}
If you set things up like that, you should be able to tell how your PD method is affecting the green bitmap, and change things accordingly.
Here is another advancement for your solution ... See Demo example
public class MainActivity extends Activity {
Bitmap bp;
Canvas bitmapCanvas;
DrawView drawImg;
LinearLayout ln1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ln1 = (LinearLayout) findViewById(R.id.ln1);
drawImg = new DrawView(this);
ln1.addView(drawImg);
}
public class DrawView extends View implements View.OnTouchListener {
private int x = 0;
private int y = 0;
Bitmap bitmap;
Path circlePath;
Paint circlePaint;
private final Paint paint = new Paint();
private final Paint eraserPaint = new Paint();
public DrawView(Context context){
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
// Set background
this.setBackgroundColor(Color.CYAN);
bp = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
// Set bitmap
bitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas();
bitmapCanvas.setBitmap(bitmap);
bitmapCanvas.drawColor(Color.TRANSPARENT);
bitmapCanvas.drawBitmap(bp, 0, 0, null);
circlePath = new Path();
circlePaint = new Paint();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
// Set eraser paint properties
eraserPaint.setAlpha(0);
eraserPaint.setStrokeJoin(Paint.Join.ROUND);
eraserPaint.setStrokeCap(Paint.Cap.ROUND);
eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
eraserPaint.setAntiAlias(true);
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawBitmap(bitmap, 0, 0, paint);
bitmapCanvas.drawCircle(x, y, 30, eraserPaint);
canvas.drawPath(circlePath, circlePaint);
}
public boolean onTouch(View view, MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
bitmapCanvas.drawCircle(x, y, 30, eraserPaint);
circlePath.reset();
circlePath.addCircle(x, y, 30, Path.Direction.CW);
int ac=event.getAction();
switch(ac){
case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, String.valueOf(x), Toast.LENGTH_SHORT).show();
circlePath.reset();
break;
}
invalidate();
return true;
}
}
}
read more