Surfaceview with bitmap touchevent - java

I have a Surfaceview Class called ChickenView and I'm trying to make my bMapEgg have a touchevent. I tried using this bMapEgg.setOnTouchListener(this);
but it didn't work. Any ideas?
public void drawCourt() {
if (ourHolder.getSurface().isValid()) {
canvas = ourHolder.lockCanvas();
//Paint paint = new Paint();
canvas.drawColor(Color.BLACK);//the background
paint.setColor(Color.argb(255, 255, 255, 255));
paint.setTextSize(45);
canvas.drawText("Score:" + score + " Lives:" + lives + " fps:" + fps, 20, 40, paint);
Bitmap bMapEgg = BitmapFactory.decodeResource(getResources(), R.drawable.egg);
bMapEgg = scaleDown(bMapEgg,180,true);
Bitmap bMapBackground = BitmapFactory.decodeResource(getResources(), R.drawable.backgrounddd);
canvas.drawBitmap(bMapBackground, 0, 0, paint);
canvas.drawBitmap(bMapEgg, ballPosition.x, ballPosition.y, paint);
ourHolder.unlockCanvasAndPost(canvas);
}
}

First, you need to setup a touch listener for the whole SurfaceView. Next, to check whether the bitmap was touched you need to do something like this:
float x = touchEvent.getX();
float y = touchEvent.gety();
// Replace these with the correct values (bitmap x, y, width & height)
float x1 = bitmapPositionX;
float x2 = x1 + bitmapWidth;
float y1 = bitmapPositionY;
float y2 = y1 + bitmapHeight;
// Test to see if touch is inside the bitmap
if (x > x1 && x < x2 && y > y1 && y < y2) {
// Bitmap was touched
switch (touchEvent.getAction()) {
case TouchEvent.ACTION_DOWN: (bitmap was just touched) break;
case TouchEvent.ACTION_DOWN: (user lifted finger from bitmap) break;
}
}

Related

can't draw shapes on canvas

I have created a custom view so that i can draw shapes on clicks and preform some action
and i have created a method called fillOnTouch(); which is supposed to take a paint and canvas as parameters then draw colored circles on the canvas when i call this method from TouchEvent it doesn't draw on the canvas so I tried to create a path called coloredCircles and have added shapes to it on Touchevent then draw this path on onDraw method but the result is the same the shapes aren't drawen in the canvas as it's supposed to be
onTouchEvent
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchStart(x, y);
coloredCircles.addCircle(x, y, 20, Path.Direction.CW);
checkStrokeInRightPath(x, y);
FillLetters.fillCircleOnTouch(x, y, fillCircles, dataLists, mCanvas);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touchMove(x, y);
checkStrokeInRightPath(x, y);
FillLetters.fillCircleOnTouch(x, y, fillCircles, dataLists, mCanvas);
coloredCircles.addCircle(x, y, 20, Path.Direction.CW);
invalidate();
break;
case MotionEvent.ACTION_UP:
touchUp();
checkStrokeInRightPath(x, y);
FillLetters.fillCircleOnTouch(x, y, fillCircles, dataLists, mCanvas);
coloredCircles.addCircle(x, y, 20, Path.Direction.CW);
invalidate();
break;
}
return true;
}
fillOnTouch Method
public static void fillCircleOnTouch(float x, float y, Paint paint, List<List<Integer>> circleList, Canvas canvas) {
List<Integer> xPoints, yPoints, circleCount;
int r = DrawLetters.radius;
float xStart, xEnd, yStart, yEnd;
if (!circleList.isEmpty()) {
xPoints = circleList.get(0);
yPoints = circleList.get(1);
circleCount = circleList.get(2);
if (iterationCount < xPoints.size()) {
float nextCircleX = xPoints.get(iterationCount);
float nextCircleY = yPoints.get(iterationCount);
paint.setColor(blendColors("#FFFF00", "#0000FF", (circleCount.get(iterationCount)) * ((float) (1.0 / xPoints.size()))));
xStart = nextCircleX - r;
xEnd = nextCircleX + r;
yStart = nextCircleY - r;
yEnd = nextCircleY + r;
Range<Float> xRange = new Range<>(xStart, xEnd);
Range<Float> yRange = new Range<>(yStart, yEnd);
if (xRange.contains(x) && yRange.contains(y)) {
canvas.drawCircle(nextCircleX, nextCircleY, r, paint);
iterationCount++;
}
}
}
}
onDraw Method
#Override
protected void onDraw(Canvas canvas) {
// save the current state of the canvas before,
// to draw the background of the canvas
canvas.save();
// DEFAULT color of the canvas
int backgroundColor = Color.WHITE;
mCanvas.drawColor(backgroundColor);
// now, we iterate over the list of paths
// and draw each path on the canvas
for (Stroke fp : paths) {
mPaint.setColor(fp.color);
mPaint.setStrokeWidth(fp.width);
mCanvas.drawPath(fp.path, mPaint);
}
if (coloredCircles != null && !coloredCircles.isEmpty()) {
canvas.drawPath(coloredCircles, mPaint);
}
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.restore();
}

Java OpenCV Layer small image onto larger image with transparency

I am trying to write a function that overlays an image at a rectangle with transparency over top of another image, However it doesn't layer the images it just erases the section that I overlay and the transparency cuts through the entire image. Here is my code.
public static void overlayImage(String imagePath, String overlayPath, int x, int y, int width, int height) {
Mat overlay = Imgcodecs.imread(overlayPath, Imgcodecs.IMREAD_UNCHANGED);
Mat image = Imgcodecs.imread(imagePath, Imgcodecs.IMREAD_UNCHANGED);
Rectangle rect = new Rectangle(x, y, width, height);
Imgproc.resize(overlay, overlay, rect.size());
Mat submat = image.submat(new Rect(rect.x, rect.y, overlay.cols(), overlay.rows()));
overlay.copyTo(submat);
Imgcodecs.imwrite(imagePath, image);
}
EDIT: Here are some example pictures:
Before:
After:
Found this function that does exactly what I needed.
public static void overlayImage(Mat background,Mat foreground,Mat output, Point location){
background.copyTo(output);
for(int y = (int) Math.max(location.y , 0); y < background.rows(); ++y){
int fY = (int) (y - location.y);
if(fY >= foreground.rows())
break;
for(int x = (int) Math.max(location.x, 0); x < background.cols(); ++x){
int fX = (int) (x - location.x);
if(fX >= foreground.cols()){
break;
}
double opacity;
double[] finalPixelValue = new double[4];
opacity = foreground.get(fY , fX)[3];
finalPixelValue[0] = background.get(y, x)[0];
finalPixelValue[1] = background.get(y, x)[1];
finalPixelValue[2] = background.get(y, x)[2];
finalPixelValue[3] = background.get(y, x)[3];
for(int c = 0; c < output.channels(); ++c){
if(opacity > 0){
double foregroundPx = foreground.get(fY, fX)[c];
double backgroundPx = background.get(y, x)[c];
float fOpacity = (float) (opacity / 255);
finalPixelValue[c] = ((backgroundPx * ( 1.0 - fOpacity)) + (foregroundPx * fOpacity));
if(c==3){
finalPixelValue[c] = foreground.get(fY,fX)[3];
}
}
}
output.put(y, x,finalPixelValue);
}
}
}

android matrix translate won't work properly

i have a problem with moving bitmap using matrix
case MotionEvent.ACTION_MOVE:
if (!ScaleDetector.isInProgress()) {
speedx = (event.getX() - downCorx);
speedy = (event.getY() - downCory);
matrix.postTranslate(speedx, speedy);
Log.e("000", speedx + "| " + speedy + "! ");
}
this.invalidate();
break;
that code works but it Accelerates the bitmap speed!
rest of the codes:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(finalBitmap, matrix, null);
}
public void setBitmap(Bitmap bitmap) {
finalBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
myCanvas = new Canvas(finalBitmap);
myCanvas.drawBitmap(bitmap, 0, 0, null);
}
is there any better way to do this?
case MotionEvent.ACTION_MOVE:
if (!ScaleDetector.isInProgress()) {
speedx = (event.getX() - downCorx);
speedy = (event.getY() - downCory);
// update your current position. So when ACTION_MOVE is triggered again, you actually calculate only the speed between the current and last event of ACTION_MOVE
downCorx = event.getX();
downCory = event.getY();
matrix.postTranslate(speedx, speedy);
Log.e("000", speedx + "| " + speedy + "! ");
}
this.invalidate();
break;

How to resize bitmap in canvas?

I can't find a answer on other questions here and on Google.
The problem is, that the Bitmaps created in GameView are too big on some screens (on my Galaxy S5 they are correct) and they should be scaled with theGameView.getDensity().
GameView class:
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.circle_green);
Circle class:
private int score;
private int y = 0;
private int x = 0;
private int Speed, width, height;
private GameView theGameView;
private Bitmap bmp;
private Random rnd;
public Circle(GameView theGameView, Bitmap bmp) {
this.theGameView = theGameView;
this.bmp = bmp;
this.width = bmp.getWidth();
this.height = bmp.getHeight();
this.score = theGameView.getScore();
rnd = new Random();
x = (int) (30 * theGameView.getDensity() + rnd.nextInt((int) (theGameView.getWidth() - width - 50 * theGameView.getDensity())));
y = (int) (60 * theGameView.getDensity() + rnd.nextInt((int) (theGameView.getHeight() - height - 80 * theGameView.getDensity())));
Speed = (int) (2 * theGameView.getDensity());
}
private void bounceOff() {
if (x + 10 * theGameView.getDensity() > theGameView.getWidth() - width - Speed || x + Speed < 10 * theGameView.getDensity()) {
Speed = -Speed;
}
x = x + Speed;
if (y + 60 * theGameView.getDensity() > theGameView.getHeight() - height - Speed || y + Speed < 60 * theGameView.getDensity()) {
Speed = -Speed;
}
y = y + Speed;
}
public void onDraw(Canvas canvas) {
bounceOff();
if(canvas != null) {
canvas.drawBitmap(bmp, x, y, null);
}
}
public boolean isTouched(float x2, float y2) {
return x2 > x && x2 < x + width && y2 > y && y2 < y + height;
}
It's very easy. Just use canvas.scale
canvas.save(); // Save current canvas params (not only scale)
canvas.scale(scaleX, scaleY);
canvas.restore(); // Restore current canvas params
scale = 1.0f will draw the same visible size bitmap

coordinates inside a canvas on android

I'm development an app for drawing lines between two points. For example:
I have a map like this (Please imagine The X are dots):
X X X X X X X X X X
Each one have been created with this sentence:
canvas.drawCircle(50, 100, 15, paint);
canvas.drawCircle(148, 100, 15, paint);
canvas.drawCircle(246, 100, 15, paint);
canvas.drawCircle(344,100,15,paint);
canvas.drawCircle(442,100,15,paint);
canvas.drawCircle(540,100,15,paint);
canvas.drawCircle(638,100,15,paint);
canvas.drawCircle(736,100,15,paint);
canvas.drawCircle(834,100,15,paint);
canvas.drawCircle(932,100,15,paint);
And I use a listener for catch the position of user interaction
case MotionEvent.ACTION_UP:
downx = event.getX();
downy = event.getY();
The problem is when I make clic between the points (932,100) and (832,100) the X position return 771 and it is not a value between 832 and 932.
This is my code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawingImageView = (ImageView) this.findViewById(R.id.DrawingImageView);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
int PMaxX=0;
int PMaxY =0;
final ArrayList<ArrayList<Integer>> Matriz = new ArrayList<ArrayList<Integer>>();
if (android.os.Build.VERSION.SDK_INT >= 13) {
display.getSize(size);
PMaxX = size.x;
PMaxY = size.y;
} else if (android.os.Build.VERSION.SDK_INT < 13) {
// Log.d("State", "Prueba menor 13");
PMaxX = display.getWidth();
PMaxY = display.getHeight();
}
Bitmap bitmap = Bitmap.createBitmap(PMaxX, PMaxY, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
paint = new Paint();
paint.setColor(Color.rgb(0, 0, 0));
paint.setStrokeWidth(10);
canvas.drawCircle(50, 100, 15, paint);
canvas.drawCircle(148, 100, 15, paint);
canvas.drawCircle(246, 100, 15, paint);
canvas.drawCircle(344,100,15,paint);
canvas.drawCircle(442,100,15,paint);
canvas.drawCircle(540,100,15,paint);
canvas.drawCircle(638,100,15,paint);
canvas.drawCircle(736,100,15,paint);
canvas.drawCircle(834,100,15,paint);
canvas.drawCircle(932,100,15,paint);
canvas.drawCircle(1065,100,15,paint);
drawingImageView.setImageBitmap(bitmap);
drawingImageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_UP:
downx = event.getX();
downy = event.getY();
Log.d("State","Show X" + Float.toString(downx));
Log.d("State","Show Y" + Float.toString(downy));
break;
default:
break;
}
return true;
}
});
}

Categories