Warp Image area on touch of a point area? - android

I need a basic idea for how can i warp image on touch of a particular area. Image filters apply warp on whole image but i want to warp single point, like if i want to warp eye of a person then i will touch on that point. So I need a basic idea about this work.
I have tried this one but its also applies filters on whole image.
https://github.com/Jtfinlay/PhotoWarp
App:
https://play.google.com/store/apps/details?id=hu.tonuzaba.android&hl=en

A warp is not just at a "single point" but over some area that you deform in a smooth way.
To achieve this, you need a geometric transform of the coordinates that works in some neighborhood of the touched point. One way to do this is by applying a square grid on the image and moving the grid nodes around the touched points with some law of yours (for instance, apply a displacement vector to all nodes, with a decaying factor such that far away nodes don't move).
Then you need a resampling function that computes the new coordinates of every pixel and copies the color of the source pixel.
For good results, you must actually work in reverse: scan the destination image and for every pixel retrieve the source coordinates and source pixels. Apply bilinear or bicubic resampling to avoid aliasing.
For ease of implementation, the gridding idea should be adapted as well: rather than deforming the destination grid, keep it unchanged and apply the inverse deformation to the source grid.
Last thing: in the grid approach, see the displacements of the grid nodes as two scalar functions DX(i, j) and DY(i, j) that you can handle separately. From the knowledge of the displacements at the nodes, you can estimate the displacement of any pixel by interpolation (bicubic would be appropriate here).

you can use canvas to detect that portion and stop action on that portion in ontouchlistener
code sample
Bitmap pricetagBmp = BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.ic_tag_circle_24dp);
// canvas.drawBitmap(pricetagBmp,left + (right - left) / 2, top + (bottom - top) / 2 - (bounds.height() / 2),circlePaint);
float imageStartX = (left + ((right-left)/2)) - (pricetagBmp.getWidth()/2);
float imageStartY = (top + ((bottom - top) / 2)) - (pricetagBmp.getHeight()/2);
canvas.drawBitmap(pricetagBmp, imageStartX, imageStartY,circlePaint);
and in ontouchlistener if that points detected you can perform no action
Note: you can replace drawBitmap with drawRect or something else with invisible color

Related

Generating Objects outside of Screen and then Moving them to Center?

Is it possible to generate a series of objects outside of the screen, and then making those objects move inwards? I am creating a live-wall paper with circles that start outside of the screen, and move inwards and bounce off the walls. I have created an illustration to better describe what i mean:
The 2 Issues im facing are:
Generating Objects outside of screen
Making them move inward and then bounce off the edges
How can i achieve this?
One solution to this problem would be to create a class which would contain following attributes:
X and Y coordinated (could be Point)
speedX
speedY
Then you could create objects with coordinates:
(X < 0) or (X > screenWidth)
and/or
(Y < 0) or (Y > screenHeight)
and give them appropriate speed (so they move towards the screen boundaries).
In each step you would:
update each object's coordinates, moving it in appropriate direction corresponding to its current speed
redraw all objects on your canvas
The offset of object's coordinates depends on time step between each two redraws. It's up to you how you want to evaluate it.
Until an object reaches screen boundaries it will be drawn outside the screen and not visible.
To draw the objects on canvas you could extend View class (or SurfaceView - difference between these two is discussed here) and override onDraw() method. You can follow this tutorial or find another one by yourself (there are lots of it).
If an object reaches the screen boundary from its inside (i.e. when its X is in range [0, screenWidth] and its Y is in range [0, screenHeight]) you can negate its speed (in X or Y direction, depending on which boundary has been reached) so it would go in the other direction (like in an elastic collision with a wall).
You can adjust speedX and speedY minimum and maximum values to see which give the most satisfying results.

Touch event for visible part of the Image

I need to apply click/touch events for only visible part of the View. Say for example a image of size 200X200. Apart from center 50X50, remaining part is transparent. I want to get touch events only for that 50X50 visible part Not on remaining transparent part.
In above image (its single image), only inner Diamond has got visible part. Apart from that Diamond is transparent area. So, if I touch Diamond then only I want to do something else ignore.
Edit :
Rachita's link helped me. I gone through that link and got idea how can I implement. But I could not understand some constants like 320, 240 etc while creating Points. In my case, I know the Diamond (in above image) x and y Ponits (hard coded values asctually). So, using those how can I determine, whether I touched inside Diamond or outside?
my Diamond points are as below
pointA = new Point(0, 183);
pointB = new Point(183, 0);
pointC = new Point(366, 183);
pointD = new Point(183, 366);
Edit :
Finally got solution from Luksprog. Its based on checking touched point pixel color. If color is 0 means, you touched transparent layer else you touched some colored part of the image. Simple, but very effective. Have a look at it here.
AFAIK you can not implement this with onclick listener or my any other direct way .You will have to use onTouchListener .
Firstly set your view dynamically at a specific (x,y) position using this How can I dynamically set the position of view in Android?
Calculate the region your diamond will occupy (you should khow the size of image inorder to calculate area of diamond)
3.Trigger a action in onTouchListener only when x, y fall in the required region. Use How to get the Touch position in android?
check this link to calculate if a given point lies in the required square
EDIT
To understand the coordinate system of android refer to this link How do android screen coordinates work?
Display mdisp = getWindowManager().getDefaultDisplay();
int maxX= mdisp.getWidth();
int maxY= mdisp.getHeight();
(x,y) :-
1) (0,0) is top left corner.
2) (maxX,0) is top right corner
3) (0,maxY) is bottom left corner
4) (maxX,maxY) is bottom right corner
here maxX and maxY are screen maximum height and width in pixels, which we have retrieved in above given code.
Remember if you want to support multiple devices with different screen sizes,make sure you use a relative value for x,y ie some ratio of screen height or width ,as different devices have different ppi
Check if touched point lies in the required polygon
I thinks these link might help you determining if the point touched (you can get x,y from onTouch event eg.event.getX()) lies in the required polygon whose points you have mentioned in the question . determine if a given point is inside the polygon and How can I determine whether a 2D Point is within a Polygon?

Best approach to make a background scrolling game?

i want to do a 2D game with backgrounds and sprites (views) moving on the screen.
I want to make a game with a scrolling ground. I mean the user must see a horizon in the top part of the screen filling the 30% of the screen size. The ground must be scrolling and must be the 70% of the screen size. For example, if i put a car on the ground, the car must be driving into a scrolling road and the sky (horizon) must be seen on the screen, in the top of the road, filling the 30% of the screen.
I am searching in google about scrolling games but i can't find the way to achieve this kind of scrolling ground game with horizon.
Any ideas and approaches will be grated, i'm just making a research about how to do this.
Thanks
This kind of effect can be done in various ways, here is one very basic example I can come up with.
First create a background image for your horizon - a blue sky with a sun would be good. Now create some detail images for the background, such as clouds and birds. These can move accross the background image from left to right (and/or vice-versa). In your rendering code you would render the "background" image first, and then the "detail" images. Make sure that your background image covers around 35% of the screen, so that when you render the 70% ground layer there is some overlap - preventing a hole where the two layers meet.
Next create a textured image for the ground. For this I would use a static image that has the correct type of texture for what you are trying to represent (such as dirt). It may also be good to add some basic detail to the top of this image (such as mountains, trees, etc).
This should be rendered after the background layer.
Once you have this layout in place, the next step would be to simulate the depth of your world. For this you would need to create objects (2D images) that would be placed in your "world". Some examples would be trees, rocks, houses, etc.
To define your world you would need to store 2 coordinates for each object - a position on the x-axis as well as a depth value on the z-axis (you could also use a y-axis component to include height, but I will omit that for this example).
You will also need to track your player's position on the same x and z axis. These values will change in realtime as the player moves into the screen - z will change based on speed, and x will change based on steering (for example).
Also define a view distance - the number of units away from the player at which objects will be visible.
Now once you have your world set up this way, the rendering is what will give the illusion of moving into the screen. First render your player object at the bottom of the ground layer. Next, for each world object, calculate it's distance to the player - if it's distance is within the view distance you defined then it should be rendered, otherwise it can be ignored.
Once you find an object that should be rendered, you need to scale it based on it's distance from the player. The formula for this scaling would be something like:
distance_from_player_z = object.z - player.z
scale = ( view_distance - distance_from_player_z ) / view_distance
This will result in a float value between 0.0 and 1.0, which can be used to scale your object's size. Using this, the larger the distance from the player, the smaller the object becomes.
Next you need to calculate the position on the x-axis and y-axis to render your object. This can be achieved with the simple 3D projection formulas:
distance_from_player_x = object.x - player.x
x_render = player.x + ( distance_from_player_x / distance_from_player_z )
y_render = ( distance_from_player_z / view_distance ) * ( height_of_background_img );
This calculates the distance of the object relative to the player on the x-axis only. It then takes this value and "projects" it, based on the distance it is away from the player on the z-axis. The result is that the farther away the object on the z-axis, the closer it is to the player on the x-axis. The y-axis part uses the distance away from the player to place the object "higher" on the background image.
So with all this information, here is a (very basic) example in code (for a single object):
// define the render size of background (resolution specific)
public final static float RENDER_SIZE_Y = 720.0f * 0.7f; // 70% of 720p
// define your view distance (in world units)
public final static float VIEW_DISTANCE = 10.0f;
// calculate the distance between the object and the player (x + z axis)
float distanceX = object.x - player.x;
float distanceZ = object.z - player.z;
// check if object is visible - i.e. within view distance and in front of player
if ( distanceZ > 0 && distanceZ <= VIEW_DISTANCE ) {
// object is in view, render it
float scale = ( VIEW_DISTANCE - distanceZ ) / VIEW_DISTANCE;
float renderSize = ( object.size * scale );
// calculate the projected x,y values to render at
float renderX = player.x + ( distanceX / distanceZ );
float renderY = ( distanceZ / VIEW_DISTANCE ) * RENDER_SIZE_Y;
// now render the object scaled to "renderSize" at (renderX, renderY)
}
Note that if distance is smaller than or equal to zero, it means that the object is behind the player, and also not visible. This is important as distanceZ==0 will cause an error, so be sure to exclude it. You may also need to tweak the renderX value, depending on resolution, but I will leave that up to you.
While this is not at all a complete implementation, it should get you going in the right direction.
I hope this makes sense to you, and if not, feel free to ask :)
Well, you can use libgdx (http://libgdx.badlogicgames.com/).
The superjumper example will put you in the right way :) (https://github.com/libgdx/libgdx/tree/master/demos/superjumper)

How to achieve tilt effect on Android like on Windows Phone?

I want to achieve a tilt effect when a button is clicked, on Android OS.
Tilt Effect: Not the whole button will be seen as pressed. Only the part that touch event occured should seem to be pressed.
Is this easily possible on Android?
A simple way would be to use canvas draws to draw 4 sided shapes.
Consider each 4 corners. The "untouched" rectangle would be full size the touched rectangle would be smaller.
You just need to draw your four sided shape using a point you calculate for each part of the rectangle. You can get the touch position, then figure out how much "weight" to give each point.
to calculate each corner, you need to figure out how much "weight" to give the touched coordinate, and how much "weight" to give the untouched coordinate. If you touch the top left corner, that corner would use 100% of the touched coordinate, and the other three corners would all use the untouched coordinate.
If you touched the top middle, you would get a shape like this:
We can calculate the corners for any touch spot, by calculating how far from the corner your touch is
float untouchedXWeight1 = Math.abs(xt - x1)/width;
//maximum of 1, minimum of 0
float untouchedYWeight1 = Math.abs(yt - y1)/height;
float untouchedWeight1 = (untouchedXWeight1 + untouchedYWeight1)/2;
//also maximum of 1, minimum of 0
float touchedWeight1 = 1 - untouchedWeight1;
so with those weights, you can calculate your x and y positions for that corner:
x1 = xUntouched1 * untouchedWeight + xTouched1 * touchedWeight1;
y1 = yUntouched1 * untouchedWeight + yTouched1 * touchedWeight1;
Then do similarly for the other 3 corners.
I've created a first draft here : https://github.com/flavienlaurent/TiltEffect
In a second step, I will make it usable with Button etc.
Unfortunatly, I didn't use the very good (but too mathematical for me) answer of HalR

how to draw a small bitmap on a large bitmap at a psition outside the screen in android?

Assuming that i have an android phone with max x=400 and max y=300
I have a 5000 by 5000 px bitmap and i display a 400 by 300 part of it on screen. I scroll it around using touch events. I want to draw a smaller bitmap(30 by 30px) onto that larger bitmap at location (460,370). But i cant statically do it(as my game requires). I want to draw and undraw that smaller image according to the player's input or collision detections.
What i am confused about is that suppose currently (50,50) to (450,350) of the larger image is displayed on the screen and now ,due to a certain requirement of the game at this moment, i have to draw that 30by30 bitmap at (460,370) but this point is in two systems - 1)In the big bitmap's co-ordinate system it's 460,370 but when it will come inside the visible area of screen it will have values something between (0,0) and (400,300) depending upon its position on the screen as per the player's movements...
So how do i track that image- i mean using which co-ordinate system, and how do i go about doing all this?
I know I've put it here in a very confusing way but that's the best way i can put it and i'll be really glad, and grateful to you if somebody could help me on this.....
Terminology:
Let's call the coordinates on the big map world coordinates
Let's call the coordinates on the screen view coordinates. You are talking to the drawing system (canvas?) in view coordinates.
Your currently displayed region of the bigger map is 100% defined by an offset, let's call this (offsetX, offsetY). Formally, this offset maps your world coordinates onto your view coordinates.
If you have the small image displayed at position (x, y) in world coordinates, all you need to do is subtract your offset to get to view coordinates, i.e.
viewX = worldX - offsetX;
viewY = worldY - offsetY;

Categories

Resources