I have the following code:
Bitmap right1;
public TicTacToe(Context context) {
super(context);
right1 = BitmapFactory.decodeResource(getResources(), R.drawable.plus);
int width = right1.getWidth();
int height = right1.getHeight();
}
#Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
right1 = Bitmap.createScaledBitmap(right1, canvas.getWidth()/3, canvas.getWidth()/3, false);
canvas.drawBitmap(right1, (canvas.getWidth() - (canvas.getWidth()/3)), 0, null);
invalidate();
}
I want to rescale the bitmap that is called "right1" based off of what the width of the canvas is. I succeeded in doing this, but the line of code that does this is the third line under the onDraw method. The problem with that line of code is that it will constantly loop when I would like to only run it once. Idealy I would like to put that line of code within the TicTacToe method, but I am unsure how to initialize the canvas within the TicTacToe method so that I can get the canvas width.
You don't need to do this stuff inside constructor just add condition in onDraw() method.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
if(right1==null){
right1 = Bitmap.createScaledBitmap(right1, canvas.getWidth() / 3, canvas.getWidth() / 3, false);
canvas.drawBitmap(right1, (canvas.getWidth() - (canvas.getWidth() / 3)), 0, null);
invalidate();
}
}
Related
I'm making an app that can freehand crop a picture using a canvas in android studio. My problem is that after cropping the picture, the cropped part stays in the same exact position as it was originally, whereas i want it to get centered and enlargened. Is there any way to take the non-transparent part and center it, or maybe remove the transparent part all-together?
Screenshot of my app where i want the banana to be centered
https://i.stack.imgur.com/8OKNT.png
Bitmap bitmap;
Path path = new Path();
Paint paint;
int width;
int height;
Rect src;
Rect dest;
public CutImage(Context context, Bitmap bitmap2) {
super(context);
bitmap = bitmap2;
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);
paint.setStrokeWidth(5f);
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();
src = new Rect(0, 0, bitmap.getWidth() - 1, bitmap.getHeight() - 1);
dest = new Rect(0, 0, width - 1, height - 1);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.getHeight();
canvas.drawBitmap(bitmap,src,dest, null);
canvas.drawPath(path, paint);
}
private void crop() {
Bitmap croppedBitmap =
Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),bitmap.getConfig());
Canvas cropCanvas = new Canvas(croppedBitmap);
Paint paint = new Paint();
cropCanvas.drawPath(path,paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
cropCanvas.drawBitmap(bitmap,src,dest,paint);
bitmap = croppedBitmap;
showImage2(bitmap);
}
} ```
I have a custom TextView with overridden onDraw() in which I mirror the text like this:
#Override
protected void onDraw(Canvas canvas) {
int cx = this.getMeasuredWidth() / 2;
int cy = this.getMeasuredHeight() / 2;
canvas.save();
if(mirrored)
{
canvas.scale(1f, -1f, cx, cy);
}
super.onDraw(canvas);
canvas.restore();
}
Now I want to scroll this mirrored canvas vertically with repeatable .scrollBy(0, -1) method in my activity.
However, when I scroll the text it is getting trimmed from top:
scroll1 scroll2
Probably something happens in the TextView method bringPointIntoView(int offset) or bringTextIntoView().
Is there a quick fix to this problem?
Thanks in advance!
So, for anybody interested I fixed this by setRotation(180) for text view and then mirroring the canvas by the X axis. Then my onDraw method became like this:
#Override
protected void onDraw(Canvas canvas) {
int cx = this.getMeasuredWidth() / 2;
int cy = this.getMeasuredHeight() /2;
canvas.save();
if(mirrored)
{
canvas.scale(-1f, 1f, cx, cy);
setRotation(180);
}
else
{
setRotation(0);
}
super.onDraw(canvas);
canvas.restore();
}
This way the scrollBy method works fine for either direction.
My application is downloading a bitmap which is later populated into custom ImageView. However I want this bitmap to be updated before it is actually drawn on a canvas (I want to add some points over it). However as the result I see only populated bitmap without changes I made. Can anyone help?
Here is my onDraw method. "bitmap" object is set via setImageBitmap received from AsyncTask in onPostExecute() method.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (bitmap != null) {
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int padding = (width - bitmap.getWidth()) / 2;
canvas.drawBitmap(bitmap, padding, 0, null);
paint.setColor(Color.RED);
paint.setStrokeWidth(5f);
for (Face face : getPhotoObject().getFaces()) {
canvas.drawPoint(face.getLeftEye().x, face.getLeftEye().y, paint);
canvas.drawPoint(face.getRightEye().x, face.getRightEye().y, paint);
}
}
}
You can create a canvas with a bitmap at any time:
Canvas canvas = new Canvas(myBitmap);
// draw code
// the resulting bitmap will be edited.
Hope this helps
The image I am using is from a 4x6. So the aspect ratio should be about .66. When I calculate the aspect ration in my code , I get around .66. However, the height of the displayed image looks squashed. The image only looks right if I set the aspect ratio manually to around .85.
Since setting the aspect ratio manually is not perfect, how can I get the can I keep the height of my image from appearing to be squashed.
public class SpotGameActivity extends Activity {
private Bitmap mBitmap;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dpi2b);
setContentView(new BitMapView(this, mBitmap));
}
class BitMapView extends View {
Bitmap mBitmap = null;
public BitMapView(Context context, Bitmap bm) {
super(context);
mBitmap = bm;
}
#Override
protected void onDraw(Canvas canvas) {
// called when view is drawn
Paint paint = new Paint();
paint.setFilterBitmap(true);
// The image will be scaled so it will fill the width, and the
// height will preserve the image’s aspect ration
float aspectRatio = ((float) mBitmap.getWidth()) / mBitmap.getHeight();
Rect dest = new Rect(0, 0, this.getWidth(),(int) (this.getHeight() * aspectRatio));
String AR = Double.toString(aspectRatio);
//Rect dest = new Rect(0, 0, getWidth(), getHeight());
canvas.drawBitmap(mBitmap, null, dest, paint);
Toast.makeText(SpotGameActivity.this, AR, Toast.LENGTH_SHORT).show();
}
}
}
Aspect = width/height
newHeight = newWidth/Aspect
Do this,
Rect dest = new Rect(0, 0, this.getWidth(),(int) (this.getWidth() / aspectRatio));
I'm making an App that needs to be able to draw new graphics on top of the last set.
This is my current onDraw() method -
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
if(points.size() > 0) {
//do some stuff here - this is all working ok
canvas.drawLine(p1.x, p1.y, p2.x, p2.y, linePaint);
}
}
Basically, I need to draw the new graphics as a layer on top of the last, so what I'm looking for is a way to carry the image of the last canvas to the current.
I have tried to figure it out myself using the canvas.setBitmap() method but it acts very funny.
Any help appreciated :)
P.S if it's needed, the the class extends SurfaceView and implements SurfaceHolder.Callback
Edit: This is what I have tried in the onDraw() method but it just force closes
if(bitmap != null) {
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.setBitmap(bitmap);
}
Found the answer myself :)
#Override
protected void onDraw(Canvas c) {
if(bitmap != null && canvas != null) {
canvas.drawLine(p1.x, p1.y, p2.x, p2.y, linePaint);
c.drawBitmap(bitmap, 0, 0, linePaint);
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);
canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
}
Works exactly as intended, it creates the effect of drawing on top of the old canvas continuously
You will have to store the previous image persistently onto a ArrayList, and during ondraw, loop through the ArrayList to redraw all items.
something like this:
for (Graphic graphic : _graphics) {
bitmap = graphic.getBitmap();
coords = graphic.getCoordinates();
canvas.drawBitmap(bitmap, coords.getX(), coords.getY(), null);
}