I am trying to overlay a image in a specific position in the video so that i can combine both.But could not place the image to exact position selected.its moving somewhere else the final output.
I am using this library to combine image and video https://github.com/MasayukiSuda/Mp4Composer-android (out of box Any other library suggestions)In this library i can set the image in 4 different positions:
public enum Position {
LEFT_TOP,
LEFT_BOTTOM,
RIGHT_TOP,
RIGHT_BOTTOM
}
mp4Composer = new Mp4Composer(inputVideoPath, videoPath)
.filter(new WatermarkFilter(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher_sample),WatermarkFilter.Position.LEFT_TOP))
In the Processing this happens:
case LEFT_TOP:
canvas.drawBitmap(bitmap,0,0,null);
break;
case LEFT_BOTTOM:
canvas.drawBitmap(bitmap, 0, canvas.getHeight() - bitmap.getHeight(), null);
break;
What i did i slightly modified my code to set anywhere in the canvas by getting the X Y position of the bitmap using MotionEvent
protected boolean onTouchDown(#NonNull MotionEvent event) {
currentMode = ActionMode.DRAG;
downX = event.getX();
downY = event.getY();
midPoint = calculateMidPoint();
oldDistance = calculateDistance(midPoint.x, midPoint.y, downX, downY);
oldRotation = calculateRotation(midPoint.x, midPoint.y, downX, downY);
currentIcon = findCurrentIconTouched();
if (currentIcon != null) {
currentMode = ActionMode.ICON;
currentIcon.onActionDown(this, event);
} else {
handlingSticker = findHandlingSticker();
}
if (handlingSticker != null) {
downMatrix.set(handlingSticker.getMatrix());
if (bringToFrontCurrentSticker) {
stickers.remove(handlingSticker);
stickers.add(handlingSticker);
}
if (onStickerOperationListener != null){
onStickerOperationListener.onStickerTouchedDown(handlingSticker);
}
}
if (currentIcon == null && handlingSticker == null) {
return false;
}
invalidate();
return true;
}
public float[] getMappedBoundPoints() {
float[] dst = new float[8];
getMappedPoints(dst, getBoundPoints());
return dst;
}
By this Method i get my X Y points
float X = sticker.getMappedBoundPoints()[0];
float Y = sticker.getMappedBoundPoints()[1];
Log.d(TAG, "SavedVideo: " + "X" + X + "?/" + "Y" + Y);
And Finally Passing my X Y to the Mp4Composer method:
.filter(new WatermarkFilter(bitmap,X,Y))
on the other side
canvas.drawBitmap(bitmap,X,Y,null);
Can anyone help out or point out where the mistake is ! Thanks
Related
I'm trying perform click using following code but here says that exists some limitations and i can see this in my tests.
But seems that this bug is caused because Rect() not contains X, Y coordenates, why everytime that i click in a place where not is supported (probably some limitation like was said on readme file on the example) is executed this line in findSmallestNodeAtPoint() routine:
if (!bounds.contains(x, y)) {
System.out.println("ERROR DETECTED!!! :::::: NOT bounds.contains(x, y) :::::::");
return null;
}
Here in this question, also is mentioned this example of Github and was gived a answer with a code example working 100% (tested) from android Nougat+ (api 24 and above), but in my case i need fix this code below to my app also support perform click in previous versions of android.
Then already knowing where this code is failing, i want know what can be made related to:
!bounds.contains(x, y)
The main part of code is:
private static void logNodeHierachy(AccessibilityNodeInfo nodeInfo, int depth) {
Rect bounds = new Rect();
nodeInfo.getBoundsInScreen(bounds);
StringBuilder sb = new StringBuilder();
if (depth > 0) {
for (int i=0; i<depth; i++) {
sb.append(" ");
}
sb.append("\u2514 ");
}
sb.append(nodeInfo.getClassName());
sb.append(" (" + nodeInfo.getChildCount() + ")");
sb.append(" " + bounds.toString());
if (nodeInfo.getText() != null) {
sb.append(" - \"" + nodeInfo.getText() + "\"");
}
System.out.println(sb.toString());
for (int i=0; i<nodeInfo.getChildCount(); i++) {
AccessibilityNodeInfo childNode = nodeInfo.getChild(i);
if (childNode != null) {
logNodeHierachy(childNode, depth + 1);
}
}
}
private static AccessibilityNodeInfo findSmallestNodeAtPoint(AccessibilityNodeInfo sourceNode, int x, int y) {
Rect bounds = new Rect();
sourceNode.getBoundsInScreen(bounds);
if (!bounds.contains(x, y)) {
System.out.println(":::::: NOT bounds.contains(x, y) :::::::");
return null;
}
for (int i=0; i<sourceNode.getChildCount(); i++) {
AccessibilityNodeInfo nearestSmaller = findSmallestNodeAtPoint(sourceNode.getChild(i), x, y);
if (nearestSmaller != null) {
return nearestSmaller;
}
}
return sourceNode;
}
public void click(int x, int y) {
System.out.println(String.format("Click [%d, %d]", x, y));
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
if (nodeInfo == null) return;
AccessibilityNodeInfo nearestNodeToMouse = findSmallestNodeAtPoint(nodeInfo, x, y);
if (nearestNodeToMouse != null) {
logNodeHierachy(nearestNodeToMouse, 0);
nearestNodeToMouse.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
nodeInfo.recycle();
}
OK, i answer my own question, already that the experts in AccessibilityService thinking that i'm building a malware and not like of help these kind of people.
Apparently seems that not is possible escape of use Rect() and getBoundsInScreen() based in this answer.
Also i found another code similar, ref:
public void click(int x, int y) {
clickAtPosition(x, y, getRootInActiveWindow());
}
public static void clickAtPosition(int x, int y, AccessibilityNodeInfo node) {
if (node == null) return;
if (node.getChildCount() == 0) {
Rect buttonRect = new Rect();
node.getBoundsInScreen(buttonRect);
if (buttonRect.contains(x, y)) {
// Maybe we need to think if a large view covers item?
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
System.out.println("1º - Node Information: " + node.toString());
}
} else {
Rect buttonRect = new Rect();
node.getBoundsInScreen(buttonRect);
if (buttonRect.contains(x, y)) {
// Maybe we need to think if a large view covers item?
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
System.out.println("2º - Node Information: " + node.toString());
}
for (int i = 0; i < node.getChildCount(); i++) {
clickAtPosition(x, y, node.getChild(i));
}
}
}
and also have trouble. But is better than code linked on question above :D.
In my tests only not was able to perform click on android virtual keyboard.
I m displaying Image and name From ArrayList>
on View I want to get Position value From The view
profileimage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
use=arraylist.get(i).get("User_Id");
new userbyid().execute();
}
});
i m getting Like this In Array List But Its Always giving Same id On image Click
I want to get Value Of view position
here is setimage fuction Where i m displaying image and name
public void settheimage(int j)
{
for (i = j; i < j+10; i++)
{
LayoutInflater inflate = (LayoutInflater)getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View m_view = inflate.inflate(R.layout.custom_layout, null);
ImageView m_image = (ImageView) m_view.findViewById(R.id.sp_image);
LinearLayout m_topLayout = (LinearLayout) m_view.findViewById(R.id.sp_color);
tempusername=(TextView)m_view.findViewById(R.id.username);
ImageView profileimage=(ImageView)m_view.findViewById(R.id.profileimage);
LinearLayout m_bottomLayout = (LinearLayout) m_view.findViewById(R.id.sp_linh);
//final RelativeLayout myRelView = new RelativeLayout(this);
m_view.setLayoutParams(new LayoutParams((windowwidth - 80), 450));
m_view.setX(40);
m_view.setY(40);
m_view.setTag(i);
Image=arraylist.get(i).get("User_Image");
tempuser_id=arraylist.get(i).get("User_Id");
username=arraylist.get(i).get("FirstName");
tempusername.setText(username);
Picasso.with(getActivity()).load(Image).into(m_image);
// m_image.setBackgroundResource(myImageList[i]);
if (i == 0) {
m_view.setRotation(-1);
} else if (i == 1) {
m_view.setRotation(-5);
} else if (i == 2) {
m_view.setRotation(3);
} else if (i == 3) {
m_view.setRotation(7);
} else if (i == 4) {
m_view.setRotation(-2);
} else if (i == 5) {
m_view.setRotation(5);
}
// ADD dynamically like button on image.
final Button imageLike = new Button(getActivity());
imageLike.setLayoutParams(new LayoutParams(100, 50));
imageLike.setBackgroundDrawable(getResources().getDrawable(R.drawable.like));
imageLike.setX(20);
imageLike.setY(-250);
imageLike.setAlpha(alphaValue);
m_topLayout.addView(imageLike);
// ADD dynamically dislike button on image.
final Button imagePass = new Button(getActivity());
imagePass.setLayoutParams(new LayoutParams(100, 50));
imagePass.setBackgroundDrawable(getResources().getDrawable(R.drawable.dislike));
imagePass.setX(260);
imagePass.setY(-300);
imagePass.setAlpha(alphaValue);
m_topLayout.addView(imagePass);
profileimage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
use=arraylist.get(i).get("User_Id");
new userbyid().execute();
}
});
m_topLayout.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
x_cord = (int) event.getRawX();
y_cord = (int) event.getRawY();
/* m_view.setX(x_cord - screenCenter + 40);
m_view.setY(y_cord - 150);*/
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = (int) event.getX();
y = (int) event.getY();
Log.v("On touch", x + " " + y);
break;
case MotionEvent.ACTION_MOVE:
x_cord = (int) event.getRawX(); // Updated for more
// smoother animation.
y_cord = (int) event.getRawY();
m_view.setX(x_cord - x);
m_view.setY(y_cord - y);
// m_view.setY(y_cord-y);
// y_cord = (int) event.getRawY();
// m_view.setX(x_cord - screenCenter + 40);
// m_view.setY(y_cord - 150);
if (x_cord >= screenCenter) {
m_view.setRotation((float) ((x_cord - screenCenter) * (Math.PI / 32)));
if (x_cord > (screenCenter + (screenCenter / 2))) {
imageLike.setAlpha(1);
if (x_cord > (windowwidth - (screenCenter / 4))) {
Likes = 2;
} else {
Likes = 0;
}
} else {
Likes = 0;
imageLike.setAlpha(0);
}
imagePass.setAlpha(0);
} else {
// rotate
m_view.setRotation((float) ((x_cord - screenCenter) * (Math.PI / 32)));
if (x_cord < (screenCenter / 2)) {
imagePass.setAlpha(1);
if (x_cord < screenCenter / 4) {
Likes = 1;
} else {
Likes = 0;
}
} else {
Likes = 0;
imagePass.setAlpha(0);
}
imageLike.setAlpha(0);
}
break;
case MotionEvent.ACTION_UP:
x_cord = (int) event.getRawX();
y_cord = (int) event.getRawY();
Log.e("X Point", "" + x_cord + " , Y " + y_cord);
imagePass.setAlpha(0);
imageLike.setAlpha(0);
if (Likes == 0) {
// Log.e("Event Status", "Nothing");
m_view.setX(40);
m_view.setY(40);
m_view.setRotation(0);
} else if (Likes == 1) {
//Toast.makeText(getActivity(), "dislike the image",Toast.LENGTH_SHORT).show();
listvalue_pos--;
if(listvalue_pos==-1)
{
i=i+10;
listvalue_pos=9;
settheimage(i);
parentView.removeView(m_view);
}
else {
parentView.removeView(m_view);
}
// new deletUSer().execute();
} else if (Likes == 2) {
//Toast.makeText(getActivity(), "like the image",Toast.LENGTH_SHORT).show();
listvalue_pos--;
if(listvalue_pos==-1)
{
i=i+10;
listvalue_pos=9;
settheimage(i);
parentView.removeView(m_view);
}
else {
parentView.removeView(m_view);
}
// new adduser().execute();
}
break;
default:
break;
}
return true;
}
});
parentView.addView(m_view);
}
}
here I m Add hashmap into arraylist
map.put("User_Id", USer_id);
map.put("FirstName",FirstName);
map.put("User_Image", USer_Image);
// Set the JSON Objects into the array
/* list.add(USer_Image);
useridlist.add(USer_id);
usernamelist.add(FirstName);*/
arraylist.add(map);
please give me the answer how to get arralist index value
You can use int index = arraylist.indexOf(yourObject);
I'm not sure that correctly understood what you wanna do
can you show screenshot?
you can set tag for your imageview
I'm writing spreadsheet app for android and for getting cell value i use dynamic edittext.
Is this any way to get info when text is written and save it to cell value?
here is part of code:
#Override
public boolean onTouchEvent(MotionEvent event){
if(Selection != null) {
Cell prevSelection = hostActivity.logic.getCell(Selection.left, Selection.top);
SelTxt = hostActivity.txtInput.getText().toString();
if(SelTxt.length() != 0 && prevSelection.GetValue() != SelTxt && prevSelection.getChanged()) {
prevSelection.setValue(SelTxt);
hostActivity.txtInput.clearComposingText();
prevSelection.Modified(false);
SelTxt = "";
}
}
switch(event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
int x = (int) event.getX();
int y = (int) event.getY();
calculateSelectionRect(x, y);
SelectionChanged = true;
if(x > startTableX && y > startTableY && !GroupSelected) {
Cell tmpCell = hostActivity.logic.getCell(Selection.left, Selection.top);
hostActivity.EditSelectedCellValue(Selection.left, Selection.top, Selection.right, Selection.bottom, tmpCell);
}
invalidate();
and
if(txtInput != null)
frameLayout.removeView(txtInput);
String tmpText = "";
txtInput = new EditText(this.getApplicationContext());
FrameLayout.LayoutParams txtParams = new FrameLayout.LayoutParams((right - left), (bottom - top));
txtInput.setX(left);
txtInput.setY(top);
txtInput.setText(value.GetValue());
txtInput.setTextColor(R.color.Selected_Cell_Border);
txtInput.setBackgroundColor(getResources().getColor(R.color.Selected_Cell));
frameLayout.addView(txtInput, txtParams);
setContentView(frameLayout);
tmpText = txtInput.getText().toString();
if(txtInput.getText().toString() != value.GetValue())
value.Modified(true);
txtInput.clearComposingText();
return tmpText;
}
in app it works in a way that after filling one cell and selecting cell directly below value is copied once, another selecting this cell gives good empty cell and is ok. But it's annoying and shouldn't happen
I'm trying to get the location of the user's finger touch and detect if it is within the bounds of an image view. I'm getting all the right integers returned to me, there is no problem with the values. The problem I'm getting is when trying to detect whether returnX is greater or less than the imageview X int.
ImageView img;
float eventX;
float eventY;
float x,y,x2,y2;
String TAG = "imgPos";
String TAG2 = "downcheck";
String TAG3 = "bounds";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
img = (ImageView)findViewById(R.id.imageView1);
}
public void fingerDownLoop(){
if (SingleTouchEventView.userDown == true){
Log.e(TAG2, "Down is true");
Thread myThread = new Thread(myRunnable);
myThread.start();
} else if (SingleTouchEventView.userDown == false){
Log.e(TAG2, "Down is false");
}
}
public void getFingerLocation(){
float returnX = SingleTouchEventView.eventX;
float returnY = SingleTouchEventView.eventY;
Log.e(TAG3, " - X -");
Log.e(TAG3, " getX: " + returnX);
Log.e(TAG3, " - Y -");
Log.e(TAG3, " getY: " + returnY);
if (returnX < x){
Log.e(TAG3, "Outside bounds");
}
if (returnX > x){
Log.e(TAG3, "Inside bounds");
}
}
Runnable myRunnable = new Runnable() {
#Override
public void run() {
while (SingleTouchEventView.userDown == true) {
try {
Log.e(TAG2, "FingerDown");
getFingerLocation();
x = img.getLeft();
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // Waits for 1 second (1000 milliseconds)
}
}
};
}
testText is a button click, it gets the imageviews position and stores it as the values. The problem I'm getting is here:
if (returnX < x){
Log.e(TAG3, "Outside bounds");
}
if (returnX > x){
Log.e(TAG3, "Inside bounds");
}
It is all ways showing as Inside bounds even though returnX is less than X. Any ideas?
Updated get img position.
int[] img_coordinates = new int[2];
img.getLocationOnScreen(img_coordinates);
double x_center = (double)img_coordinates[0] + img.getWidth()/2.0;
double y_center = (double)img_coordinates[1] + img.getHeight()/2.0;
int halfwidth = 150 / 2;
int halfheight = 150 / 2;
yboundtop = y_center - halfheight;
yboundbottom = y_center + halfheight;
xboundleft = x_center - halfwidth;
xboundright = x_center + halfwidth;
float returnX = eventX;
float returnY = eventY;
if (returnX < xboundleft || returnX > xboundright || returnY < yboundtop || returnY > yboundbottom) {
Log.e(TAG3, "Outside bounds");
}
if (returnX > xboundleft && returnX < xboundright && returnY > yboundtop && returnY < yboundbottom) {
Log.e(TAG3, "Inside bounds");
}
I'am not sure what you want to accomplish by your code, but checking in a loop is not very efficient and in this case probably not necessary.
Your imageView has a method getHitRect() and you could use it like this:
Rect hitRect = new Rect();
imageView.getHitRect(hitRect);
if(hitRect.contains(touchEvent.getX(), touchEvent.getY())){
// your touch is inside, do something useful
}
Use it inside your touch-method
Now that I kind of know what you are looking for I think I may be able to help. Override the onTouchEvent() method of your Activity to capture your touch events. This will be much more efficient than doing the loop yourself.
private boolean mTouchInImage = false;
public boolean onTouchEvent(MotionEvent event) {
boolean handledTouch = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Rect hitRect = new Rect((int)img.getX(), (int)img.getY(),
(int)(mg.getX() + img.getWidth()), (int)(img.getY() + img.getHeight()));
handledTouch = mTouchInImage = hitRect.contains((int)event.getX(), (int)event.getY());
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
handledTouch = mTouchInImage;
mTouchInImage = false;
break;
case MotionEvent.ACTION_MOVE:
if (mTouchInImage) {
img.setX(event.getX() - img.getWidth() / 2);
img.setY(event.getY() - img.getHeight() / 2);
img.invalidate();
handledTouch = true;
}
break;
}
return handledTouch;
}
I was reading this post about getting an angle between 2 points and was wondering. I thought atan2 is defined for atan2(y,x) here it is atan2(deltaX, deltaY), why is x first now?
public float getAngle(Point target) {
float angle = (float) Math.toDegrees(Math.atan2(target.x - x, target.y - y));
if (angle < 0) {
angle += 360;
}
return angle;
}
Math.java it define as
public static double atan2(double y, double x) {
return StrictMath.atan2(y, x); // default impl. delegates to StrictMath
}
and this will return the counter-clock wise angle with respect to X- axis.
If you interchange those two you will get the clock wise angle with respect to X- axis.
In Cartesian coordinate system we consider counter-clock wise angle with respect to X-axis. That is why Math.java use this as above.
Swapping the order of the arguments means that instead of the (counter-clockwise) angle with the X-axis you get the (clockwise) angle with the Y-axis. It's not wrong, just unusual.
Try this out:
// ... code
Target start = new Target();
start.setX(0);
start.setY(0);
Target aLine = new Target();
Target bLine = new Target();
aLine.setX(-65000);
aLine.setY(ress.getObstacle().getLine());
bLine.setX(65000);
bLine.setY(ress.getObstacle().getLine());
Line2D line = new Line2D.Float(aLine.getX(), aLine.getY(), bLine.getX(), bLine.getY());
List<Target> list = new ArrayList<Target>();
if (!(ress.getObstacle().getLine() == 0)) {
//check if points are there , if yes just reinitialize a linea-lineb and calculate the same in for:
String a = "";
try {
a = ress.getObstacle().getA().toStrin`enter code here`g();
} catch (NullPointerException e) {
}
if (!(a == "")) {
aLine.setX(ress.getObstacle().getA().getX());
aLine.setY(ress.getObstacle().getLine());
bLine.setX(ress.getObstacle().getB().getX());
bLine.setY(ress.getObstacle().getLine());
Line2D lineNew = new Line2D.Float(aLine.getX(), aLine.getY(), bLine.getX(), bLine.getY());
for (Target t : ress.getTargets()) {
Line2D line2 = new Line2D.Float(start.getX(), start.getY(), t.getX(), t.getY());
if (!line2.intersectsLine(lineNew)) {
list.add(t);
}
}
} else {
//-------------------start old part----------------------------------
for (Target t : ress.getTargets()) {
Line2D line2 = new Line2D.Float(start.getX(), start.getY(), t.getX(), t.getY());
if (!line2.intersectsLine(line)) {
list.add(t);
}
}
///////-------end old part
}
} else {
double angA = Math.toDegrees(StrictMath.atan2(ress.getObstacle().getA().getX() - start.getX(), ress.getObstacle().getA().getY() - start.getY()));
double angB = Math.toDegrees(StrictMath.atan2(ress.getObstacle().getB().getX() - start.getX(), ress.getObstacle().getB().getY() - start.getY()));
Boolean up = (ress.getObstacle().getA().getY()>0)&(ress.getObstacle().getB().getY()>0);
Boolean left = (ress.getObstacle().getA().getX()<0)&(ress.getObstacle().getB().getX()<0);
Boolean right = (ress.getObstacle().getA().getX()>0)&(ress.getObstacle().getB().getX()>0);
for (Target t : ress.getTargets()) {
double angT = Math.toDegrees(StrictMath.atan2(t.getX() - start.getX(), t.getY() - start.getY()));
if (up) {
if (!((angT > Math.min(angA,angB)) & (angT < Math.max(angB,angA))))
list.add(t);
} else
if (right || left) {
if ( !((angT > Math.min(angA,angB)) & (angT< Math.max(angB,angA)))) {
list.add(t);
}
} else
{
if ( ((angT > Math.min(angA,angB)) & (angT< Math.max(angB,angA)))) {
list.add(t);
}
}
}
}
sol.setTargets(list);