When we try to ZoomIn and ZoomOut on Xamarin Android, several color shades are occur Android version 7 and 8 only - xamarin.android

In cameraPageRenderer, we handle zoomIn and zoomOut in our application. When we try to ZoomIn and ZoomOut, several colour shades occur. Please take a look at this image. As a result, we are resolving this issue by handling PrepareAndStartCamera (). Please see the code snippet below.
public override bool OnTouchEvent(MotionEvent e)
{
switch (e.Action & MotionEventActions.Mask)
{
case MotionEventActions.Down:
oldDist = getFingerSpacing(e);
break;
case MotionEventActions.Move:
float newDist = getFingerSpacing(e);
if (newDist > oldDist)
{
//mCamera is your Camera which used to take picture, it should already exit in your custom Camera
handleZoom(true, camera);
}
else if (newDist < oldDist)
{
handleZoom(false, camera);
}
oldDist = newDist;
break;
}
return true;
}
private static float getFingerSpacing(MotionEvent e)
{
if (e.PointerCount == 2)
{
float x = e.GetX(0) - e.GetX(1);
float y = e.GetY(0) - e.GetY(1);
return (float)Math.Sqrt(x * x + y * y);
}
return 0;
}
private void handleZoom(bool isZoomIn, global::Android.Hardware.Camera camera)
{
//camera.StopPreview();
// camera.Release();
// camera = global::Android.Hardware.Camera.Open((int)cameraType);
global::Android.Hardware.Camera.Parameters parameters = camera.GetParameters();
if (parameters.IsZoomSupported)
{
int maxZoom = parameters.MaxZoom;
int zoom = parameters.Zoom;
if (isZoomIn && zoom < maxZoom)
{
zoom++;
}
else if (zoom > 0)
{
zoom--;
}
parameters.Zoom = zoom;
camera.SetParameters(parameters);
camera.SetPreviewTexture(surfaceTexture);
// PrepareAndStartCamera();
}
else
{
Android.Util.Log.Error("lv", "zoom not supported");
}
}
After using PrepareAndStartCamera(), when ZoomingIn or ZoomingOut the camera and taking a picture, it returns to the normal size picture. if we are not using this PrepareAndStartCamera() method, then the Color shades are appear.
private void PrepareAndStartCamera()
{
try
{
camera.StopPreview();
var display = activity.WindowManager.DefaultDisplay;
if (display.Rotation == SurfaceOrientation.Rotation0)
{
camera.SetDisplayOrientation(90);
}
if (display.Rotation == SurfaceOrientation.Rotation270)
{
camera.SetDisplayOrientation(180);
}
camera.StartPreview();
}
}

Related

How to show zooming scalling values shows in camerapage android xamarin

Currently i am implementing zoomin and zoomout in camerapagerenderer but while zoomin and zoomout scalling values not shown in UI view, how to achieve this in android for above screenshot try to achive like these
public override bool OnTouchEvent(MotionEvent e)
{
switch (e.Action & MotionEventActions.Mask)
{
case MotionEventActions.Down:
oldDist = getFingerSpacing(e);
break;
case MotionEventActions.Move:
float newDist = getFingerSpacing(e);
if (newDist > oldDist)
{
//mCamera is your Camera which used to take picture, it should already exit in your custom Camera
handleZoom(true, camera);
}
else if (newDist < oldDist)
{
handleZoom(false, camera);
}
oldDist = newDist;
break;
}
return true;
}
private void handleZoom(bool isZoomIn, global::Android.Hardware.Camera camera)
{
global::Android.Hardware.Camera.Parameters parameters = camera.GetParameters();
if (parameters.IsZoomSupported)
{
int maxZoom = parameters.MaxZoom;
int zoom = parameters.Zoom;
if (isZoomIn && zoom < maxZoom)
{
zoom++;
}
else if (zoom > 0)
{
zoom--;
}
parameters.Zoom = zoom;
camera.SetPreviewTexture(surfaceTexture);
PrepareAndStartCamera();
}

Zoomin percentage values shows in cameralayout in android xamarin forms

Currently am implementing zoomin and zoomout using twofingers zoomin and zoomout works as expected but we are showing percentage values in while zoomin and zoomout if possible to show the values using Textview or anyother way to show the zooming percentage values in view in android xamarin
public override bool OnTouchEvent(MotionEvent e)
{
switch (e.Action & MotionEventActions.Mask)
{
case MotionEventActions.Down:
oldDist = getFingerSpacing(e);
break;
case MotionEventActions.Move:
float newDist = getFingerSpacing(e);
if (newDist > oldDist)
{
//mCamera is your Camera which used to take picture, it should already exit in your custom Camera
handleZoom(true, camera);
}
else if (newDist < oldDist)
{
handleZoom(false, camera);
}
oldDist = newDist;
break;
}
return true;
}
private void handleZoom(bool isZoomIn, global::Android.Hardware.Camera camera)
{
global::Android.Hardware.Camera.Parameters parameters = camera.GetParameters();
var s = camera.GetParameters().ZoomRatios;
if (parameters.IsZoomSupported)
{
int maxZoom = parameters.MaxZoom;
int zoom = parameters.Zoom;
if (isZoomIn && zoom < maxZoom)
{
zoom++;
}
else if(zoom > 0)
{
zoom--;
}
parameters.Zoom = zoom;
var zoomValue = Convert.ToDecimal(s[zoom]);
zoomValue = Math.Round((zoomValue / 100), 2);
Toast toast = Toast.MakeText(Android.App.Application.Context, _languageCache.Translate(zoomValue + "%"), ToastLength.Short);
toast.SetGravity(GravityFlags.Center, 0, 0);
toast.Show();
camera.SetParameters(parameters);
PrepareAndStartCamera();
}
else
{
Android.Util.Log.Error("lv", "zoom not supported");
}
}
private static float getFingerSpacing(MotionEvent e)
{
if(e.PointerCount==2)
{
int pointerIndex = e.FindPointerIndex(_activePointerId);
float x = e.GetX(pointerIndex);
float y = e.GetY(pointerIndex);
return (float)Math.Sqrt(x * x + y * y);
}
}
You could use the ZoomRatios to get the zoom ratios of all zoom values. Use the zoom ratios in 1/100 increments. The list is sorted from small to large. The first element is always 100. The last element is the zoom ratio of the maximum zoom value.
You could call this after IsZoomSupported in handleZoom method.
var s = camera.GetParameters().ZoomRatios;
var zoomValue = Convert.ToDecimal(s[zoom]);
value = Math.Round((zoomValue / 100), 2);
You could set the percentage like value + "x":
2.5x // a zoom of 2.5x is returned as 250.
After that you could show this value with a dialpg alert or custom the camera layout as your own.
Update:
Add a TextView to show the zoom value in the screen like below.
<TextView
android:layout_width="50dp"
android:layout_height="50dp"
android:elevation="10dp"
android:id="#+id/textView1" />
And then set the value in your OnTouchEvent.
if (value != 0)
{
textView.Text = value+"x";
}

detect a screen touch outside the spinnersearch view

i have created an android app via xamarin.android. i have a multispinnersearch in a fragment and when opened normally, all the items inside it are preselected. but i had a problem. if the user touches the screen outside the spinner, the latter closes and all the items get into my list. i don't want that. unless he clicks "ok" in the spinner, no items should be taken to my list. so i tried to handle the touch event to prevent the selection of items on screen touch but it didn't work. here are the codes i tried:
public override bool DispatchTouchEvent(MotionEvent ev)
{
if (ev.Action == MotionEventActions.Down)
{
View v = CurrentFocus;
if (v is MultiSpinnerSearch)
{
Rect outRect = new Rect();
v.GetGlobalVisibleRect(outRect);
if (!outRect.Contains((int)ev.RawX, (int) ev.RawY))
{
Toast.MakeText(this, "shgsg", ToastLength.Long).Show();
}
}
}
return base.DispatchTouchEvent(ev);
}
i tried this in my main activity but i didn't work. then i tried this in my fragment on the ontouch listener interface:
if (e.Action == MotionEventActions.Down)
{
if (labors_dropdown.IsFocused == true)
{
Android.Graphics.Rect rect = new Rect();
labors_dropdown.GetGlobalVisibleRect(rect);
if (!rect.Contains((int)e.RawX, (int)e.RawY))
{
Toast.MakeText(this.Context, "gfgf", ToastLength.Short).Show();
}
}
}
it didn't work too, what should i do? thanks in advance.
You could try the below method:
public override bool DispatchTouchEvent(MotionEvent ev)
{
if (ev.Action == MotionEventActions.Down)
{
View v = (MultiSpinnerSearch)FindViewById<MultiSpinnerSearch>(Resource.Id.xxxxx);
if (!IsTouchPointInView(v, (int)ev.GetX(), (int)ev.GetY()))
{
Toast.MakeText(this, "shgsg", ToastLength.Long).Show();
}
}
return base.DispatchTouchEvent(ev);
}
private bool IsTouchPointInView(View targetView, int currentX, int currentY)
{
if (targetView == null)
{
return false;
}
int[] localtion = new int[2];
targetView.GetLocationOnScreen(localtion);
int left = localtion[0];
int top = localtion[1];
int right = left + targetView.MeasuredWidth;
int bottom = top + targetView.MeasuredHeight;
if (currentY >= top && currentY <= bottom && currentX >= left
&& currentX <= right)
{
return true;
}
return false;
}

How to draw rectangle when form is resized

enter code hereI'm using OpenCv and displaying frames which i get from video file on the imagebox. Now I'm drawing multiple rectangles on the frame and trying to move and delete them. This is working fine. But, when i'm resizing the form...i can't draw,move or delete the rectangles at the correct position as the frame coordinates are not getting changed but only imagebox coordinates are being changed and the frame is fitted into it.Please help me out.
black rectangle is where i have drawn the rectangle after form is resized...red rectangle is where the rectangle is being drawn
private void imageBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
drawRect = true;
RectStartpt = e.Location;
if (count > 0)
{
foreach (Rectangle allRect in Rect_List)
{
rect_count++;
if (allRect.Contains(e.Location))
{
Cursor cursor = Cursors.Cross;
drawRect = false;
RectStartpt = new Point(e.X, e.Y);
rect = allRect;
break;
}
}
}
}this.Invalidate();}
private void imageBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left && e.Button != MouseButtons.Right)
{
return;
}
else if (e.Button == MouseButtons.Left)
{
Point EndPt = new Point(e.X, e.Y);
Size shift = new Size(Math.Abs(RectStartpt.X - EndPt.X), Math.Abs(RectStartpt.Y - EndPt.Y));
if (drawRect == true)
{
rect.Location = new Point(Math.Min(RectStartpt.X, EndPt.X), Math.Min(RectStartpt.Y, EndPt.Y));
rect.Size = shift;
count = 1;
}
else if (drawRect == false)
{
rect.X += e.X - RectStartpt.X;
rect.Y += e.Y - RectStartpt.Y;
RectStartpt = new Point(e.X, e.Y);
}
}
}
private void imageBox1_MouseUp(object sender, MouseEventArgs e)
{
if (frame != null)
{
if (drawRect == true)
{
frame.Draw(rect, new Bgr(Color.Red), 2);
Rect_List.Add(rect);
}
else if (drawRect == false)
{
frame.Draw(rect, new Bgr(Color.Red), 2);
Rect_List.RemoveAt(rect_count - 1);
Rect_List.Add(rect);
if (Timer_enabled == false)
{
frame = captureFrame.QueryFrame().ToImage<Bgr, Byte>();
foreach (Rectangle allRect in Rect_List)
{
frame.Draw(allRect, new Bgr(Color.Red), 2);
}
imageBox1.Image = frame;
imageBox1.Refresh();
rect = new Rectangle();
frame_no++;
}
}
imageBox1.Image = frame;
imageBox1.Refresh();
//rect = new Rectangle();
rect_count = 0;
}
}
private void Form1_Resize(object sender, EventArgs e)
{
formGraphics = null;
formGraphics = imageBox1.CreateGraphics();
frame = frame.Resize(imageBox1.Width, imageBox1.Height, Inter.Linear);
imageBox1.Image = frame;
}

Processing with tuio

hi i am new to processing and i'm trying to figure out how to make the sphere move from left to right using a marker instead of the mouse. can you help me please? i can use the marker to shoot but i cant move the sphere by shooting
import TUIO.*;
TuioProcessing tuioClient;
HashMap symbols=new HashMap();
PFont fontA;
int sphereDiameter = 50;
boolean shoot = false;
float obj_size = 60;
int randx()
{
return int(random(600));
}
int[] sphereXCoords = { randx(), randx(), randx(), randx(), randx() };
int[] sphereYCoords = { 0, 0, 0, 0, 0 };
void setup()
{
size(1000,700);
tuioClient = new TuioProcessing(this);
}
void draw()
{
Vector<TuioObject> tuioObjectList =tuioClient.getTuioObjects();
Collections.sort(tuioObjectList, comp);
for (TuioObject tobj:tuioObjectList) {
fill(50, 50, 100);
int id = tobj.getSymbolID();
int x = tobj.getScreenX(width);
int y = tobj.getScreenY(height);
rect(x, y, obj_size, obj_size);
String txt="?";
if (symbols.containsKey(id)) {// if it's one in symbols, then look it up
txt = (String)symbols.get(id);
}
fill(255);
text(txt, x, y);
}
int[] sphereXCoords = { randx(), randx(), randx(), randx(), randx() };
fill(100, 0, 0);
// draw the answer box
// ellipse(answerX, answerY, obj_size, obj_size);
fill(255);
// write the answer text
// text(""+answer, answerX, answerY);
background(1);
fill(color(255,255,0));
stroke(color(0,255,0));
triangle(mouseX-8, 580, mouseX+8, 580, mouseX, 565);
fill(color(255,0,0));
stroke(color(255,0,0));
if(shoot==true)
{
sphereKiller( mouseX);
shoot = false;
}
sphereDropper();
//gameEnder();
}
Comparator<TuioObject> comp = new Comparator<TuioObject>() {
// Comparator object to compare two TuioObjects on the basis of their x position
// Returns -1 if o1 left of o2; 0 if they have same x pos; 1 if o1 right of o2
public int compare(TuioObject o1, TuioObject o2) {
if (o1.getX()<o2.getX()) {
return -1;
}
else if (o1.getX()>o2.getX()) {
return 1;
}
else {
return 0;
}
}
};
void mousePressed()
{
shoot = true;
}
void sphereDropper()
{
stroke(255);
fill(255);
for (int i=0; i<5; i++)
{
ellipse(sphereXCoords[i], sphereYCoords[i]++,
sphereDiameter, sphereDiameter);
}
}
void sphereKiller(int shotX)
{
boolean hit = false;
for (int i = 0; i < 5; i++)
{
if((shotX >= (sphereXCoords[i]-sphereDiameter/2)) &&
(shotX <= (sphereXCoords[i]+sphereDiameter/2)))
{
hit = true;
line(mouseX, 565, mouseX, sphereYCoords[i]);
ellipse(sphereXCoords[i], sphereYCoords[i],
sphereDiameter+25, sphereDiameter+25);
sphereXCoords[i] = randx();
sphereYCoords[i] = 0;
}
}
if(hit == false)
{
line(mouseX, 565, mouseX, 0);
}
}
/* void gameEnder()
{
for (int i=0; i< 5; i++)
{
if(sphereYCoords[i]==600)
{
fill(color(255,0,0));
noLoop();
}
}
}*/
void addTuioObject(TuioObject tobj) {
}
// called when an object is removed from the scene
void removeTuioObject(TuioObject tobj) {
}
/ / called when an object is moved
void updateTuioObject (TuioObject tobj) {
if(tobj.getSymbolID() == 32)
{
shoot = true;
}
}
// called when a cursor is added to the scene
void addTuioCursor(TuioCursor tcur) {
}
// called when a cursor is moved
void updateTuioCursor (TuioCursor tcur) {
}
// called when a cursor is removed from the scene
void removeTuioCursor(TuioCursor tcur) {
}
// called after each message bundle
// representing the end of an image frame
void refresh(TuioTime bundleTime) {
//redraw();
}
What do you mean by "shooting" ?
So you have your tuioClient and you initialize it in setup(). Thats good, because then the callback methods (addTuioObject, removeTuioObject, updateTuioObject, addTuioCursor, updateTuioCursor, removeTuioCursor, refresh) will fire whenever your sketch receives a TUIO message.
Keep in mind that TUIO is based on OSC which is transported over UDP. That means the tracker (reactivision & co) will have to send to the IP and port your sketch is listening to. If both are on the same machine use 127.0.0.1 and port 3333 (default).
Have a look at the examples. You'll find them in the processing "IDE" click:
"File -> Examples"
and Navigate to
"Contributed Libraries -> TUIO"

Resources