I am looking for an animation liberary of code which will help me to do 360 degree animation using set of images (Around 60 images for horizontal rotation). Also images are in SDCARD and not in application.
Thank You
You can create a custom view and override onDraw(Canvas) method and draw the bitmap of desired image.
You can keep track on the current "direction" in degree and calculate which should be displayed in what location using Canvas.drawBitmap(Bitmap,Matrix,Paint).
Here's an example of moving one image according to phone orientation.
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
public class SkySurfaceView extends SurfaceView implements OnTouchListener {
private static final String TAG = SkySurfaceView.class.getSimpleName();
private double viewPortX, viewPortY;
private int starX, starY;
private Bitmap target;
private int targetWidth, targetHeight;
private int vpWidth, vpHeight;
private Matrix skyMatrix, skyMatrix2;
private Matrix skyMatrix3;
private Bitmap star;
private Paint paint;
private Rect touchRect, touchRect2, touchRect3;
public SkySurfaceView(Context context, AttributeSet attr) {
super(context, attr);
viewPortX = viewPortY = 0;
skyMatrix = new Matrix();
skyMatrix2 = new Matrix();
skyMatrix3 = new Matrix();
paint = new Paint();
paint.setStrokeWidth(1);
paint.setDither(true);
paint.setColor(Color.RED);
Options opt = new Options();
opt.inSampleSize = 2;
opt.inScaled = false;
opt.inPreferredConfig = Config.RGB_565;
star = BitmapFactory.decodeResource(getResources(), R.drawable.star,
opt);
touchRect = new Rect(0, 0, star.getWidth(), star.getHeight());
touchRect2 = new Rect(0, 0, star.getWidth(), star.getHeight());
touchRect3 = new Rect(0, 0, star.getWidth(), star.getHeight());
this.setWillNotDraw(true);
setLayerType(View.LAYER_TYPE_HARDWARE, null);
this.setOnTouchListener(this);
getHolder().setFormat(PixelFormat.RGB_565);
}
public void setTarget(Bitmap b) {
target = b;
targetHeight = target.getHeight();
targetWidth = target.getWidth();
}
public void init() {
this.starX = (int) (vpWidth * Math.random()) + vpWidth;
this.starY = (int) ((vpHeight - star.getHeight()) * Math.random());
Log.i(TAG, "drawn star on " + starX + "," + starY);
Canvas c = new Canvas();
Log.i(TAG,
"target dimension is " + target.getWidth() + "x"
+ target.getHeight());
Bitmap bitmap = Bitmap.createBitmap(target.getWidth(),
target.getHeight(), Config.RGB_565);
c.setBitmap(bitmap);
c.drawBitmap(target, 0, 0, paint);
c.drawBitmap(star, starX, starY, paint);
c.drawBitmap(star, starX - targetWidth, starY, paint);
target.recycle();
setTarget(bitmap);
setWillNotDraw(false);
}
#Override
public boolean performClick() {
super.performClick();
return false;
}
/**
*
* #param x
* - [-1:1]
* #param y
* - [-1:1]
*/
public void setViewPort(double x, double y) {
viewPortX = x;
viewPortY = y;
int tempX = (int) (targetWidth * (viewPortX));
int tempY = (int) (targetHeight * (viewPortY - 1));
tempY = Math.max(tempY, -(targetHeight - vpHeight) / 2);
tempY = Math.min(tempY, +(targetHeight - vpHeight / 2));
Log.i(TAG,
String.format("%d %d , %d %d, %d %d", tempX, tempY, tempX
- targetWidth, tempY, tempX + targetWidth, tempY));
skyMatrix.reset();
skyMatrix.postTranslate(tempX, tempY);
skyMatrix2.reset();
skyMatrix2.postTranslate(tempX - targetWidth, tempY);
skyMatrix3.reset();
skyMatrix3.postTranslate(tempX + targetWidth, tempY);
int xx = (tempX + starX);
while (xx < targetWidth) {
xx += targetWidth;
}
touchRect.offsetTo(xx % targetWidth, (tempY + starY) % targetHeight);
touchRect2.offsetTo(xx % targetWidth - targetWidth, (tempY + starY)
% targetHeight);
touchRect3.offsetTo(xx % targetWidth + targetWidth, (tempY + starY)
% targetHeight);
postInvalidate();
}
public void setViewportSize(int x, int y) {
vpWidth = x;
vpHeight = y;
}
#Override
protected void onDraw(Canvas c) {
super.onDraw(c);
c.drawBitmap(target, skyMatrix, paint);
c.drawBitmap(target, skyMatrix2, paint);
c.drawBitmap(target, skyMatrix3, paint);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
float ex = event.getX();
float ey = event.getY();
Log.i(TAG, "touched " + ex + " " + ey);
if (touchRect.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
} else if (touchRect2.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
} else if (touchRect3.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
}
return false;
}
public void setListener(OnStarCaptureListener listener) {
this.listener = listener;
}
}
In this example, "target" is a sky image. Whenever setViewPort is called, (x and y [-1:1]), the image's drawing matrix is updated and "invalidate()" is called. The onDraw() method call will draw the "target" with offset.
Related
I am graphically representing audio on x and y axis. From those y-axis points I want to generate audio again.
Followed https://github.com/billthefarmer/scope this to get points on y-axis. I have all of the values of y-axis points. These points can be used to represent a wave graphically.
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Locale;
// Scope
public class Scope extends View {
private int width;
private int height;
private Path path;
private Canvas cb;
private Paint paint;
private Bitmap bitmap;
private Bitmap graticule;
protected boolean storage;
protected boolean clear;
protected float step;
protected float scale;
protected float start;
protected float index;
protected float yscale;
protected boolean points;
protected MainActivity.Audio audio;
// Scope
public Scope(Context context, AttributeSet attrs) {
super(context, attrs);
// Create path and paint
path = new Path();
paint = new Paint();
}
// On size changed
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// Get dimensions
width = w;
height = h;
// Create a bitmap for trace storage
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
cb = new Canvas(bitmap);
// Create a bitmap for the graticule
graticule = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(graticule);
// Black background
canvas.drawColor(Color.BLACK);
// Set up paint
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.argb(255, 0, 63, 0));
// Draw graticule
for (int i = 0; i < width; i += MainActivity.SIZE)
canvas.drawLine(i, 0, i, height, paint);
canvas.translate(0, height / 2);
for (int i = 0; i < height / 2; i += MainActivity.SIZE) {
canvas.drawLine(0, i, width, i, paint);
canvas.drawLine(0, -i, width, -i, paint);
}
// Draw the graticule on the bitmap
cb.drawBitmap(graticule, 0, 0, null);
cb.translate(0, height / 2);
}
private int max;
// On draw
#Override
protected void onDraw(Canvas canvas) {
// Check for data
if ((audio == null) || (audio.data == null)) {
canvas.drawBitmap(graticule, 0, 0, null);
return;
}
// Draw the graticule on the bitmap
if (!storage || clear) {
cb.drawBitmap(graticule, 0, -height / 2, null);
clear = false;
}
// Calculate x scale etc
float xscale = (float) (2.0 / ((audio.sample / 100000.0) * scale));
int xstart = Math.round(start);
int xstep = Math.round((float) 1.0 / xscale);
int xstop = Math.round(xstart + ((float) width / xscale));
if (xstop > audio.length)
xstop = (int) audio.length;
// Calculate y scale
if (max < 4096)
max = 4096;
yscale = (float) (max / (height / 2.0));
max = 0;
// Draw the trace
path.rewind();
path.moveTo(0, 0);
if (xscale < 1.0) {
for (int i = 0; i < xstop - xstart; i += xstep) {
if (max < Math.abs(audio.data[i + xstart]))
max = Math.abs(audio.data[i + xstart]);
float x = (float) i * xscale;
float y = -(float) audio.data[i + xstart] / yscale;
path.lineTo(x, y);
Log.d("y values", "y = " + String.valueOf(y)); // KING
writeToFile("y = " + String.valueOf(y), getContext());
}
} else {
for (int i = 0; i < xstop - xstart; i++) {
if (max < Math.abs(audio.data[i + xstart]))
max = Math.abs(audio.data[i + xstart]);
float x = (float) i * xscale;
float y = -(float) audio.data[i + xstart] / yscale;
path.lineTo(x, y);
Log.d("y values", "y = " + String.valueOf(y)); // KING
writeToFile("y = " + String.valueOf(y), getContext());
// Draw points at max resolution
if (points) {
path.addRect(x - 2, y - 2, x + 2, y + 2, Path.Direction.CW);
path.moveTo(x, y);
Log.d("y values", "y = " + String.valueOf(y)); // KING
writeToFile("y = " + String.valueOf(y), getContext());
}
}
}
// Green trace
paint.setColor(Color.GREEN);
paint.setAntiAlias(true);
cb.drawPath(path, paint);
// Draw index
if (index > 0 && index < width) {
// Yellow index
paint.setColor(Color.YELLOW);
paint.setAntiAlias(false);
cb.drawLine(index, -height / 2, index, height / 2, paint);
paint.setAntiAlias(true);
paint.setTextSize(height / 48);
paint.setTextAlign(Paint.Align.LEFT);
// Get value
int i = Math.round(index / xscale);
if (i + xstart < audio.length) {
float y = -audio.data[i + xstart] / yscale;
// Draw value
String s = String.format(Locale.getDefault(), "%3.2f",
audio.data[i + xstart] / 32768.0);
cb.drawText(s, index, y, paint);
}
paint.setTextAlign(Paint.Align.CENTER);
// Draw time value
if (scale < 100.0) {
String s = String.format(Locale.getDefault(),
(scale < 1.0) ? "%3.3f" :
(scale < 10.0) ? "%3.2f" : "%3.1f",
(start + (index * scale)) /
MainActivity.SMALL_SCALE);
cb.drawText(s, index, height / 2, paint);
// Log.d("y values", "y = " + String.valueOf(y));
} else {
String s = String.format(Locale.getDefault(), "%3.3f",
(start + (index * scale)) /
MainActivity.LARGE_SCALE);
cb.drawText(s, index, height / 2, paint);
}
}
canvas.drawBitmap(bitmap, 0, 0, null);
}
private void writeToFile(String data, Context context) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput("Sinusoids.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
} catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
// On touch event
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
// Set the index from the touch dimension
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
index = x;
break;
case MotionEvent.ACTION_MOVE:
index = x;
break;
case MotionEvent.ACTION_UP:
index = x;
break;
}
return true;
}
}
Generate byte array from y-axis points. The array can then be converted to sound.
I am developing face app like "Aging Booth". I have successfully detected face and applied wrinkle on it.
Now I want to warp face like as following example
Can any one help me to solve this problem, by guiding me which technique I should use, OR any source code to warp image like this.
I try to solve it using following code.
But it is not giving required result. So any one please edit it to get required result OR any other technique....
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class MainActivity extends Activity {
////////////////////////////////////////////////////////
ImageView img;
Bitmap face;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
LinearLayout ll01 = (LinearLayout) findViewById(R.id.linearLayout1);
SampleView sv = new SampleView(this);
ll01.addView(sv);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private static class SampleView extends View {
static int WIDTH = 8; // sections
static int HEIGHT = 8;
static int COUNT = (WIDTH + 1) * (HEIGHT + 1); // total verts count
Bitmap mBitmap; // declaring a bitmap
float[] matrixVertsMoved = new float[COUNT * 2]; // declaring an array with double amount of vert count, one for x and one for y
float[] matrixOriganal = new float[COUNT * 2];
float clickX;
float clickY;
static void setXY(float[] array, int index, float x, float y) {
array[index * 2 + 0] = x;
array[index * 2 + 1] = y;
}
///
public SampleView(Context context) {
super(context);
setFocusable(true);
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.w);
// construct our mesh
int index = 0;
for (int y = 0; y <= HEIGHT; y++) {
float fy = mBitmap.getHeight() * y / HEIGHT;
for (int x = 0; x <= WIDTH; x++) {
float fx = mBitmap.getWidth() * x / WIDTH;
setXY(matrixVertsMoved, index, fx, fy);
setXY(matrixOriganal, index, fx, fy);
index += 1;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, matrixVertsMoved, 0, null, 0, null);
Paint p1 = new Paint();
p1.setColor(0x660000FF);
Paint p2 = new Paint();
p2.setColor(0x99FF0000);
Paint p3 = new Paint();
p3.setColor(0xFFFFFB00);
for (int i = 0; i < COUNT * 2; i += 2) {
float x = matrixOriganal[i + 0];
float y = matrixOriganal[i + 1];
canvas.drawCircle(x, y, 4, p1);
float x1 = matrixOriganal[i + 0];
float y1 = matrixOriganal[i + 1];
float x2 = matrixVertsMoved[i + 0];
float y2 = matrixVertsMoved[i + 1];
canvas.drawLine(x1, y1, x2, y2, p1);
}
for (int i = 0; i < COUNT * 2; i += 2) {
float x = matrixVertsMoved[i + 0];
float y = matrixVertsMoved[i + 1];
canvas.drawCircle(x, y, 4, p2);
}
canvas.drawCircle(clickX, clickY, 6, p3);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void smudge() {
for (int i = 0; i < COUNT * 2; i += 2) {
float xOriginal = matrixOriganal[i + 0];
float yOriginal = matrixOriganal[i + 1];
float dist_click_to_origin_x = clickX - xOriginal; // distance from current vertex in the original matrix to the place clicked.
float dist_click_to_origin_y = clickY - yOriginal;
float kv_kat = dist_click_to_origin_x * dist_click_to_origin_x + dist_click_to_origin_y * dist_click_to_origin_y;
float pull = (1000000 / kv_kat / (float) Math.sqrt(kv_kat));
if (pull >= 1) {
matrixVertsMoved[i + 0] = clickX;
matrixVertsMoved[i + 1] = clickY;
} else {
matrixVertsMoved[i + 0] = xOriginal + dist_click_to_origin_x * pull;
matrixVertsMoved[i + 1] = yOriginal + dist_click_to_origin_y * pull;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#Override
public boolean onTouchEvent(MotionEvent event) {
clickX = event.getX();
clickY = event.getY();
smudge(); // change the matrix.
invalidate(); // calls a redraw on the canvas.
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
public Bitmap ExtendBitmap(Bitmap normalImage){
int w = normalImage.getWidth();
int h = normalImage.getHeight();
int thirdWidht = w / 3;
//create a new blank image
Bitmap stretchImage = Bitmap.createBitmap(w + thirdWidht, h, Bitmap.Config.ARGB_8888 );
Canvas c = new Canvas(stretchImage);
//draw left bit
c.drawBitmap(normalImage, new Rect(0,0,thirdWidht,h), new Rect(0,0,thirdWidht,h), null);
//draw stretched middle bit
c.drawBitmap(normalImage, new Rect(thirdWidht,0,thirdWidht * 2, h), new Rect(thirdWidht,0,thirdWidht * 3,h), null);
//draw right bit
c.drawBitmap(normalImage, new Rect(thirdWidht * 2,0,w,h), new Rect(thirdWidht * 3,0,w + thirdWidht,h), null);
return stretchImage;
}
I have a custom view where in I'm drawing 6 circles using canvas in Android. Those circles act as Page indicators; which means that on the click of each circle (drawn using canvas), the different items are being displayed in a view pager. Now my requirement is to set individual focus to each circles and set different accessibility to each one. Please help. Thanks in advance.
Thanks,
Rakesh
I had to use ExploreByTouchHelper to achieve my requirement as explained by #alanv and #pskink in the comment.
https://youtu.be/ld7kZRpMGb8?t=1196
Thanks guys!
You should take position of the view with View.getX() and View.getY() to get x and y of the upper left corner and also assuming You know the radius (or able to obtain width/height of the view to determine radius). After that, obtain :
xTouch = MotionEvent.getX();
yTouch = MotionEvent.getY();
Then check the condition if:
(xTouch - (x + radius)) * (xTouch - (x + radius)) + (yTouch - (y + radius)) * (yTouch - (y + radius)) <= radius * radius
The formula is just interpretation of schools geometry for determining if dot is inside circle area or not. Refer to circle equation for Cartesian coordinates for more details.
Values explanation is:
(x + radius) and (y + radius) is the center of circle.
(xTouch - (x + radius)) is distance from touch point to center by X.
(yTouch - (y + radius)) is distance from touch point to center by Y.
for the accessibility of the each circle and the accessibility text to be read it out if the TackBack is turned on then so the code for the complete scenario is:
package com.example.hello_world;
import java.util.Locale;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity implements OnInitListener {
String mText_To_Speach_text;
private int MY_DATA_CHECK_CODE = 0;
TextToSpeech myTTS;
int initStatus = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
Intent checkTTSIntent = new Intent();
checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
}
class MyView extends View {
private Path mPath, mPath2, mPath3, mPath4, mPath5;
private Paint mPaint;
private RectF mOval, mOval2;
Region mRegion1, mRegion2, mRegion3, mRegion4, mRegion5, mRegion6;
public MyView(Context context) {
super(context);
mPath = new Path();
mPath2 = new Path();
mPath3 = new Path();
mPath4 = new Path();
mPath5 = new Path();
mPaint = new Paint();
mPaint.setColor(0xffff0000);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mPath.reset();
mPath.addCircle((w / 2) - 120, h / 2, 30, Direction.CW);
mPath.close();
mPath2.reset();
mPath2.addCircle((w / 2) - 60, h / 2, 30, Direction.CW);
mPath2.close();
mPath3.reset();
mPath3.addCircle(w / 2, h / 2, 30, Direction.CW);
mPath3.close();
mPath4.reset();
mPath4.addCircle((w / 2) + 60, h / 2, 30, Direction.CW);
mPath4.close();
mPath5.reset();
mPath5.addCircle((w / 2) + 120, h / 2, 30, Direction.CW);
mPath5.close();
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xffffffff);
mPaint.setStyle(Style.FILL);
canvas.drawPath(mPath, mPaint);
canvas.drawPath(mPath2, mPaint);
canvas.drawPath(mPath3, mPaint);
canvas.drawPath(mPath4, mPaint);
canvas.drawPath(mPath5, mPaint);
RectF rectF1 = new RectF();
mPath.computeBounds(rectF1, true);
mRegion1 = new Region();
mRegion1.setPath(mPath, new Region((int) rectF1.left,
(int) rectF1.top, (int) rectF1.right, (int) rectF1.bottom));
RectF rectF2 = new RectF();
mPath2.computeBounds(rectF2, true);
mRegion2 = new Region();
mRegion2.setPath(mPath2, new Region((int) rectF2.left,
(int) rectF2.top, (int) rectF2.right, (int) rectF2.bottom));
RectF rectF3 = new RectF();
mPath3.computeBounds(rectF3, true);
mRegion3 = new Region();
mRegion3.setPath(mPath3, new Region((int) rectF3.left,
(int) rectF3.top, (int) rectF3.right, (int) rectF3.bottom));
RectF rectF4 = new RectF();
mPath4.computeBounds(rectF4, true);
mRegion4 = new Region();
mRegion4.setPath(mPath4, new Region((int) rectF4.left,
(int) rectF4.top, (int) rectF4.right, (int) rectF4.bottom));
RectF rectF5 = new RectF();
mPath5.computeBounds(rectF5, true);
mRegion5 = new Region();
mRegion5.setPath(mPath5, new Region((int) rectF5.left,
(int) rectF5.top, (int) rectF5.right, (int) rectF5.bottom));
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mRegion1.contains(x, y)) {
mText_To_Speach_text = "Circle1";
speakWords(mText_To_Speach_text);
} else if (mRegion2.contains(x, y)) {
mText_To_Speach_text = "Circle2";
speakWords(mText_To_Speach_text);
} else if (mRegion3.contains(x, y)) {
mText_To_Speach_text = "Circle3";
speakWords(mText_To_Speach_text);
} else if (mRegion4.contains(x, y)) {
mText_To_Speach_text = "Circle4";
speakWords(mText_To_Speach_text);
} else if (mRegion5.contains(x, y)) {
mText_To_Speach_text = "Circle5";
speakWords(mText_To_Speach_text);
}
}
return true;
}
}
private void speakWords(String speech) {
myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, null);
}
#Override
public void onInit(int status) {
if (initStatus == TextToSpeech.SUCCESS) {
if (myTTS.isLanguageAvailable(Locale.US) == TextToSpeech.LANG_AVAILABLE)
myTTS.setLanguage(Locale.US);
} else if (initStatus == TextToSpeech.ERROR) {
Toast.makeText(this, "Sorry! Text To Speech failed...",
Toast.LENGTH_LONG).show();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
myTTS = new TextToSpeech(this, this);
} else {
Intent installTTSIntent = new Intent();
installTTSIntent
.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installTTSIntent);
}
}
}
}
I've run into a wall with this basic drawRect not showing anything and I cannot figure out why.
onDraw
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawCircle(circle1x, circle1y, circleRadius, circlePaint);
canvas.drawCircle(circle2x, circle2y, circleRadius, circlePaint);
canvas.drawRect(rect, rectPaint);
}
setupCropping
Is running before the onDraw and is called from the View constructor to set up all the var's
private void setupCropping() {
final float scale = getContext().getResources().getDisplayMetrics().density;
circleRadius = (int) (circleRadiusDp * scale + 0.5f);
DisplayMetrics metrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
displayX = metrics.widthPixels;
displayY = metrics.heightPixels;
cropAreaY = displayY / 3;
cropAreaX = displayX;
//Setting up the circles for adjusting
circle1x = displayX / 2;
circle1y = displayY / 2 - (cropAreaY / 2);
circle2x = displayX / 2;
circle2y = displayY / 2 + (cropAreaY / 2);
canvasPaint = new Paint();
canvasPaint.setColor(0xffffff00);
circlePaint = new Paint();
circlePaint.setColor(0xffffff00);
circlePaint.setAntiAlias(true);
rectPaint = new Paint();
rectPaint.setColor(0xffffff00);
rect = new Rect();
rect.set(0, circle1y, 0, displayY - cropAreaY - circle1y);
}
The drawCircle works perfectly and draws as I'd expect it, I've checked the numbers being given to drawRect and they are set as they should be so I really don't know what could be going wrong here.
Full View class
package com.samplersnapshoot.domiq.samplersnapshoot;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.CountDownLatch;
/**
* Created by domix on 14.8.2015..
*/
public class CroppingView extends View {
public final String TAG = "DEBUG";
private Canvas cropCanvas;
private Bitmap canvasBitmap;
private int displayX;
private int displayY;
private int circle1x = 0;
private int circle2x = 0;
private int circle1y = 0;
private int circle2y = 0;
private int circleRadiusDp = 20;
private int circleRadius = 100;
private int cropAreaX = 0;
private int cropAreaY = 0;
private Rect rect;
private Paint canvasPaint;
private Paint circlePaint;
private Paint rectPaint;
public CroppingView(Context context, AttributeSet attrs){
super(context, attrs);
setupCropping();
}
private void setupCropping() {
final float scale = getContext().getResources().getDisplayMetrics().density;
circleRadius = (int) (circleRadiusDp * scale + 0.5f);
DisplayMetrics metrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
displayX = metrics.widthPixels;
displayY = metrics.heightPixels;
cropAreaY = displayY / 3;
cropAreaX = displayX;
//Setting up the circles for adjusting
circle1x = displayX / 2;
circle1y = displayY / 2 - (cropAreaY / 2);
circle2x = displayX / 2;
circle2y = displayY / 2 + (cropAreaY / 2);
canvasPaint = new Paint();
canvasPaint.setColor(0xffffff00);
circlePaint = new Paint();
circlePaint.setColor(0xffffff00);
circlePaint.setAntiAlias(true);
rectPaint = new Paint();
rectPaint.setARGB(50, 135, 225, 255);
}
/*#Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
displayX = widthMeasureSpec;
displayY = heightMeasureSpec;
invalidate();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}*/
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//Getting bitmap
getPath myPath = new getPath();
final File myFile = myPath.getLastModifiedFile();
final CountDownLatch latch = new CountDownLatch(1);
Thread getCanvasBitmap = new Thread() {
public void run() {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inDither = true;
opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
int i = 0;
while (canvasBitmap == null && ++i < 500) {
System.gc();
Log.d(TAG, "Trying again: " + i);
canvasBitmap = BitmapFactory.decodeFile(myFile.getAbsolutePath(), opt);
}
latch.countDown();
}
};
getCanvasBitmap.start();
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
//Turning into mutable bitmap
myFile.getParentFile().mkdirs();
RandomAccessFile randomAccessFile = null;
try {
randomAccessFile = new RandomAccessFile(myFile, "rw");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int bWidth = canvasBitmap.getWidth();
int bHeight = canvasBitmap.getHeight();
FileChannel channel = randomAccessFile.getChannel();
MappedByteBuffer map = null;
try {
map = channel.map(FileChannel.MapMode.READ_WRITE, 0, bWidth*bHeight*4);
} catch (IOException e) {
e.printStackTrace();
}
canvasBitmap.copyPixelsToBuffer(map);
canvasBitmap.recycle();
this.canvasBitmap = Bitmap.createBitmap(bWidth, bHeight, Bitmap.Config.ARGB_8888);
map.position(0);
this.canvasBitmap.copyPixelsFromBuffer(map);
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
randomAccessFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
Log.d(TAG, "Display vars:" + displayX + " " + displayY);
canvas.drawCircle(circle1x, circle1y, circleRadius, circlePaint);
canvas.drawCircle(circle2x, circle2y, circleRadius, circlePaint);
rect = new Rect();
rect.set(5, circle1y, displayX, displayY - cropAreaY - circle1y);
canvas.drawRect(rect, rectPaint);
}
}
The class is far from well coded, I have yet to integrate a lot of functionality and clean it up.
rect.set(0, circle1y, 0, displayY - cropAreaY - circle1y);
Both your left and right coordinates are 0. Go figure.
It's
rect.set(int left, int top, int right, int bottom);
EDIT:
Okay I managed to pinpoint the issue. The following line is in your View class
rect.set(5, circle1y, displayX, displayY - cropAreaY - circle1y);
Using the same calculations in your code, for a device with a 480x800 display, I'm getting the following coordinate values.
rect.set(5, 267, 480, 267);
Again, you have overlapping sides of your Rect; Both your top and bottom sides are on the same Y coordinate. This will produce a rectangle of 262 pixels wide and ZERO HEIGHT.
All you need to do is to update your coordinates calculation and supply the proper coordinates. Otherwise, your Rect should draw just fine.
I am making a n app that uses an android phone s accelerometer, I currently have the x value set as the variable mX (that is restricted from 0 - 10) now I have an ImageView widget that I want to rotate left if mX is lower than 5 and rotate right if mX is higher than 5 and reset to horizontal when mX is 5. My problem is that I have tried using animations, matrixs but they don't work . Please help and thanks in advance.
Enjoy this code. If helpful, let me know:
public int getDeviceDefaultOrientation() {
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Configuration config = getResources().getConfiguration();
int rotation = windowManager.getDefaultDisplay().getRotation();
if ( ((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
config.orientation == Configuration.ORIENTATION_LANDSCAPE)
|| ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&
config.orientation == Configuration.ORIENTATION_PORTRAIT)) {
return Configuration.ORIENTATION_LANDSCAPE;
} else {
return Configuration.ORIENTATION_PORTRAIT;
}
}
I got a similar example
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
public class SkySurfaceView extends SurfaceView implements OnTouchListener {
private static final String TAG = SkySurfaceView.class.getSimpleName();
private double viewPortX, viewPortY;
private int starX, starY;
private Bitmap target;
private int targetWidth, targetHeight;
private int vpWidth, vpHeight;
private Matrix skyMatrix, skyMatrix2;
private Matrix skyMatrix3;
private Bitmap star;
private Paint paint;
private Rect touchRect, touchRect2, touchRect3;
public SkySurfaceView(Context context, AttributeSet attr) {
super(context, attr);
viewPortX = viewPortY = 0;
skyMatrix = new Matrix();
skyMatrix2 = new Matrix();
skyMatrix3 = new Matrix();
paint = new Paint();
paint.setStrokeWidth(1);
paint.setDither(true);
paint.setColor(Color.RED);
Options opt = new Options();
opt.inSampleSize = 2;
opt.inScaled = false;
opt.inPreferredConfig = Config.RGB_565;
star = BitmapFactory.decodeResource(getResources(), R.drawable.star,
opt);
touchRect = new Rect(0, 0, star.getWidth(), star.getHeight());
touchRect2 = new Rect(0, 0, star.getWidth(), star.getHeight());
touchRect3 = new Rect(0, 0, star.getWidth(), star.getHeight());
this.setWillNotDraw(true);
setLayerType(View.LAYER_TYPE_HARDWARE, null);
this.setOnTouchListener(this);
getHolder().setFormat(PixelFormat.RGB_565);
}
public void setTarget(Bitmap b) {
target = b;
targetHeight = target.getHeight();
targetWidth = target.getWidth();
}
public void init() {
this.starX = (int) (vpWidth * Math.random()) + vpWidth;
this.starY = (int) ((vpHeight - star.getHeight()) * Math.random());
Log.i(TAG, "drawn star on " + starX + "," + starY);
Canvas c = new Canvas();
Log.i(TAG,
"target dimension is " + target.getWidth() + "x"
+ target.getHeight());
Bitmap bitmap = Bitmap.createBitmap(target.getWidth(),
target.getHeight(), Config.RGB_565);
c.setBitmap(bitmap);
c.drawBitmap(target, 0, 0, paint);
c.drawBitmap(star, starX, starY, paint);
c.drawBitmap(star, starX - targetWidth, starY, paint);
target.recycle();
setTarget(bitmap);
setWillNotDraw(false);
}
#Override
public boolean performClick() {
super.performClick();
return false;
}
/**
*
* #param x
* - [-1:1]
* #param y
* - [-1:1]
*/
public void setViewPort(double x, double y) {
viewPortX = x;
viewPortY = y;
int tempX = (int) (targetWidth * (viewPortX));
int tempY = (int) (targetHeight * (viewPortY - 1));
tempY = Math.max(tempY, -(targetHeight - vpHeight) / 2);
tempY = Math.min(tempY, +(targetHeight - vpHeight / 2));
Log.i(TAG,
String.format("%d %d , %d %d, %d %d", tempX, tempY, tempX
- targetWidth, tempY, tempX + targetWidth, tempY));
skyMatrix.reset();
skyMatrix.postTranslate(tempX, tempY);
skyMatrix2.reset();
skyMatrix2.postTranslate(tempX - targetWidth, tempY);
skyMatrix3.reset();
skyMatrix3.postTranslate(tempX + targetWidth, tempY);
int xx = (tempX + starX);
while (xx < targetWidth) {
xx += targetWidth;
}
touchRect.offsetTo(xx % targetWidth, (tempY + starY) % targetHeight);
touchRect2.offsetTo(xx % targetWidth - targetWidth, (tempY + starY)
% targetHeight);
touchRect3.offsetTo(xx % targetWidth + targetWidth, (tempY + starY)
% targetHeight);
postInvalidate();
}
public void setViewportSize(int x, int y) {
vpWidth = x;
vpHeight = y;
}
#Override
protected void onDraw(Canvas c) {
super.onDraw(c);
c.drawBitmap(target, skyMatrix, paint);
c.drawBitmap(target, skyMatrix2, paint);
c.drawBitmap(target, skyMatrix3, paint);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
float ex = event.getX();
float ey = event.getY();
Log.i(TAG, "touched " + ex + " " + ey);
if (touchRect.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
} else if (touchRect2.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
} else if (touchRect3.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
}
return false;
}
public void setListener(OnStarCaptureListener listener) {
this.listener = listener;
}
}
In this class, "target" is the image to be moved according to the viewport. Upon "setViewPort" is called (x and y values from -1 to 1), the view is invalidated and the onDraw() method will draw the image with offset.