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.
Related
I have added the proper native classes on Zxing in my Android project. The camera view of zxing scan is not showing in the right size. I have added the screenshot of the camera app. The scanner part of the camera should be displayed in the middle of the screen. Currently, it is displaying in at the top right corner, which is not correct. Please help me fix this issue.
**Complete View holder Java class code is added below.**
package com.scan;
import com.google.zxing.ResultPoint;
import com.scan.camera.CameraManager;
import com.ofss.digx.mobile.android.allied.R;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public final class ViewfinderView extends View {
private static final int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64};
private static final long ANIMATION_DELAY = 80L;
private static final int CURRENT_POINT_OPACITY = 0xA0;
private static final int MAX_RESULT_POINTS = 20;
private static final int POINT_SIZE = 6;
private CameraManager cameraManager;
private final Paint paint;
private Bitmap resultBitmap;
private final int maskColor;
private final int resultColor;
private final int laserColor;
private final int resultPointColor;
private int scannerAlpha;
private List<ResultPoint> possibleResultPoints;
private List<ResultPoint> lastPossibleResultPoints;
// This constructor is used when the class is built from an XML resource.
public ViewfinderView(Context context, AttributeSet attrs) {
super(context, attrs);
// Initialize these once for performance rather than calling them every time in onDraw().
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Resources resources = getResources();
maskColor = resources.getColor(R.color.viewfinder_mask);
resultColor = resources.getColor(R.color.result_view);
laserColor = resources.getColor(R.color.viewfinder_laser);
resultPointColor = resources.getColor(R.color.possible_result_points);
scannerAlpha = 0;
possibleResultPoints = new ArrayList<>(5);
lastPossibleResultPoints = null;
}
public void setCameraManager(CameraManager cameraManager) {
this.cameraManager = cameraManager;
}
#Override
public void onDraw(Canvas canvas) {
if (cameraManager == null) {
return; // not ready yet, early draw before done configuring
}
Rect frame = cameraManager.getFramingRect();
Rect previewFrame = cameraManager.getFramingRectInPreview();
if (frame == null || previewFrame == null) {
return;
}
int width = canvas.getWidth();
int height = canvas.getHeight();
// Draw the exterior (i.e. outside the framing rect) darkened
paint.setColor(resultBitmap != null ? resultColor : maskColor);
canvas.drawRect(0, 0, width, frame.top, paint);
canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
canvas.drawRect(0, frame.bottom + 1, width, height, paint);
if (resultBitmap != null) {
// Draw the opaque result bitmap over the scanning rectangle
paint.setAlpha(CURRENT_POINT_OPACITY);
canvas.drawBitmap(resultBitmap, null, frame, paint);
} else {
// Draw a red "laser scanner" line through the middle to show decoding is active
paint.setColor(laserColor);
paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
int middle = frame.height() / 2 + frame.top;
canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
float scaleX = frame.width() / (float) previewFrame.width();
float scaleY = frame.height() / (float) previewFrame.height();
List<ResultPoint> currentPossible = possibleResultPoints;
List<ResultPoint> currentLast = lastPossibleResultPoints;
int frameLeft = frame.left;
int frameTop = frame.top;
if (currentPossible.isEmpty()) {
lastPossibleResultPoints = null;
} else {
possibleResultPoints = new ArrayList<>(5);
lastPossibleResultPoints = currentPossible;
paint.setAlpha(CURRENT_POINT_OPACITY);
paint.setColor(resultPointColor);
synchronized (currentPossible) {
for (ResultPoint point : currentPossible) {
canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
frameTop + (int) (point.getY() * scaleY),
POINT_SIZE, paint);
}
}
}
if (currentLast != null) {
paint.setAlpha(CURRENT_POINT_OPACITY / 2);
paint.setColor(resultPointColor);
synchronized (currentLast) {
float radius = POINT_SIZE / 2.0f;
for (ResultPoint point : currentLast) {
canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
frameTop + (int) (point.getY() * scaleY),
radius, paint);
}
}
}
// Request another update at the animation interval, but only repaint the laser line,
// not the entire viewfinder mask.
postInvalidateDelayed(ANIMATION_DELAY,
frame.left - POINT_SIZE,
frame.top - POINT_SIZE,
frame.right + POINT_SIZE,
frame.bottom + POINT_SIZE);
}
}
public void drawViewfinder() {
Bitmap resultBitmap = this.resultBitmap;
this.resultBitmap = null;
if (resultBitmap != null) {
resultBitmap.recycle();
}
invalidate();
}
/**
* Draw a bitmap with the result points highlighted instead of the live scanning display.
*
* #param barcode An image of the decoded barcode.
*/
public void drawResultBitmap(Bitmap barcode) {
resultBitmap = barcode;
invalidate();
}
public void addPossibleResultPoint(ResultPoint point) {
List<ResultPoint> points = possibleResultPoints;
synchronized (points) {
points.add(point);
int size = points.size();
if (size > MAX_RESULT_POINTS) {
// trim it
points.subList(0, size - MAX_RESULT_POINTS / 2).clear();
}
}
}
}
----------
**XML Code is added below**
<?xml version="1.0" encoding="UTF-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<SurfaceView android:id="#+id/preview_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.scan.ViewfinderView
android:id="#+id/viewfinder_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="#+id/status_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:background="#color/transparent"
android:text="#string/msg_default_status"
android:textColor="#color/status_text"
android:textSize="14sp"/>
</FrameLayout>
I am using the framework that is described in the (great) book Beginning Android Games by Mario Zechner and Robert Green. So far all has been going great, where I can utilize the framework to draw my bitmaps for the main menu. With the framework, I am also able to clear the background, which also works great. However, when it comes to drawing pixels, lines, or shapes in general, I am completely stuck as they are not drawn. The methods execute in a similar fashion to that of the two working methods and my debugging with logging has told me that they do execute, however nothing new appears on the screen.
One source( canvas.drawLine() not appearing on bitmap ) said to draw onto a bitmap and then draw the bitmap onto the canvas, but I already made sure to do this. My paint is not null either. When drawing a rectangle, I made sure that its height and width were greater than 0. When drawing a line, I tried setting a width to 10 and the fill the STROKE. However, all of this was in vain.
Here is the code for the graphics class
import android.content.res.AssetManager;
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.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.RectF;
import com.learnplex.framework.Graphics;
import com.learnplex.framework.Pixmap;
import java.io.IOException;
import java.io.InputStream;
public class AndroidGraphics implements Graphics {
AssetManager assets;
Bitmap frameBuffer;
Canvas canvas;
Paint paint;
Rect srcRect = new Rect();
Rect dstRect = new Rect();
public AndroidGraphics(AssetManager assets, Bitmap frameBuffer) {
this.assets = assets;
this.frameBuffer = frameBuffer;
this.canvas = new Canvas(frameBuffer);
this.paint = new Paint();
}
public Pixmap newPixmap(String fileName, PixmapFormat format) {
Config config = null;
if (format == PixmapFormat.RGB565)
config = Config.RGB_565;
else if (format == PixmapFormat.ARGB4444)
config = Config.ARGB_4444;
else
config = Config.ARGB_8888;
Options options = new Options();
options.inPreferredConfig = config;
InputStream in = null;
Bitmap bitmap = null;
try {
in = assets.open(fileName);
bitmap = BitmapFactory.decodeStream(in);
if (bitmap == null)
throw new RuntimeException("Couldn't load bitmap from asset '"
+ fileName + "'");
} catch (IOException e) {
throw new RuntimeException("Couldn't load bitmap from asset '"
+ fileName + "'");
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
if (bitmap.getConfig() == Config.RGB_565)
format = PixmapFormat.RGB565;
else if (bitmap.getConfig() == Config.ARGB_4444)
format = PixmapFormat.ARGB4444;
else
format = PixmapFormat.ARGB8888;
return new AndroidPixmap(bitmap, format);
}
public void clear(int color) {
canvas.drawRGB((color & 0xff0000) >> 16, (color & 0xff00) >> 8,
(color & 0xff));
}
public void drawPixel(int x, int y, int color) {
paint.setColor(color);
canvas.drawPoint(x, y, paint);
}
public void drawLine(int x, int y, int x2, int y2, int color) {
paint.setColor(color);
canvas.drawLine(x, y, x2, y2, paint);
}
public void drawRect(int x, int y, int width, int height, int color) {
paint.setColor(color);
paint.setStyle(Style.FILL);
canvas.drawRect(x, y, x + width - 1, y + width - 1, paint);
}
public void drawArc(int x, int y, int width, int height, int startAngle, int sweepAngle, int color) {
paint.setColor(color);
RectF oval = new RectF(x, y, x + width - 1, y + height -1);
canvas.drawArc(oval, startAngle, sweepAngle, true, paint); // true is usecenter, idk what it does yet
}
public void drawPixmap(Pixmap pixmap, int x, int y, int srcX, int srcY,
int srcWidth, int srcHeight) {
srcRect.left = srcX;
srcRect.top = srcY;
srcRect.right = srcX + srcWidth - 1;
srcRect.bottom = srcY + srcHeight - 1;
dstRect.left = x;
dstRect.top = y;
dstRect.right = x + srcWidth - 1;
dstRect.bottom = y + srcHeight - 1;
canvas.drawBitmap(((AndroidPixmap) pixmap).bitmap, srcRect, dstRect, null);
}
public void drawPixmap(Pixmap pixmap, int x, int y) {
canvas.drawBitmap(((AndroidPixmap)pixmap).bitmap, x, y, null);
}
public int getWidth() {
return frameBuffer.getWidth();
}
public int getHeight() {
return frameBuffer.getHeight();
}
}
As I said, the drawPixmap class works, as well as the clear class
And here is the relevant part of the implementation
public void present(float deltaTime){
Graphics g = game.getGraphics();
g.clear(0xffffff); //From here down works - clears background and makes white
g.drawPixmap(Assets.getTitle(), 240, 20 ); // Display title
g.drawPixmap(Assets.getStart(), 540, 300); // Display start button
g.drawPixmap(Assets.getScore(), 590, 550); // Display score button / connect with google play
g.drawPixmap(Assets.getThemeScreen(),740, 550); // Display theme screen
if(Settings.soundEnabled) // Display sound icon
g.drawPixmap(Assets.getSoundOn(), 440, 550);
else
g.drawPixmap(Assets.getSoundOff(), 440, 550);
g.drawLine(100, 200, 300, 400, 0x000000); //This does not work - draws black line
}
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.
Why does this AI class doesn't draw to the canvas?
package com.dragon.game;
import android.graphics.*;
import com.dragon.game.Game.*;
import java.util.*;
public class AI {
public static Bitmap a;
int x, y, dirX, dirY;
int width, height;
long start, stop;
boolean fg = true;
SurView ov;
Random r = new Random();
public AI(SurView surView, Bitmap ai){
a = ai;
ov = surView;
width = a.getWidth();
height = a.getHeight();
x = Remote.wt / 4;
y = Remote.wt / 4;
}
public void update(){
x++;
}
public void onDraw(Canvas canvas){
if(fg){
x = Remote.wt / 4;
y = Remote.wt / 4;
fg = false;
}
update();
Rect src = new Rect(0, 0, width, height);
Rect dst = new Rect(x, y, x + Remote.pw, y + Remote.pw);
canvas.drawBitmap(a, src, dst, null);
}
}
The reason is that you have initialized Bitmap a inside Public AI method and then you are using it inside onDraw method , you cannot do this , either you have to initialize it globally or you have to give a reference to it
I've some sample code that comes with Android that distorts a bitmap image(Bitmapmesh.java). I'm wanting a circle placed on my image that gives a fisheye effect. I'm new to android and especially graphics, is it possible to create this effect in the bitmapmesh sample?
I'm not sure where to start with this so any pointers would be appreciated. Can anyone give me a high level view of what's involved, eg i'd like to place a circle on the image firstly. i've placed buttons over images before that seem to float, this was done by using a relative layout then adding child buttons. what i'm tring to do now is different and will probably involve calling some onDraw method? i also have an algorithm that does the distortion, i'm just not sure how to apply this to the image.
Below is the bitmapmesh code. Can anyone talk me through where to start, even if it's just placing the circle on the image first, then i can tackle implementing the effect.
thanks mat
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import android.content.Context;
import android.graphics.;
import android.os.Bundle;
import android.os.Environment;
import android.view.;
import android.util.FloatMath;
public class BitMapFishEye extends GraphicsActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
private static class SampleView extends View {
private static final int WIDTH = 20;
private static final int HEIGHT = 20;
private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1);
private final Bitmap mBitmap;
private final float[] mVerts = new float[COUNT*2];
private final float[] mOrig = new float[COUNT*2];
private final Matrix mMatrix = new Matrix();
private final Matrix mInverse = new Matrix();
private File tempFile;
private byte[] imageArray;
private 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.beach);*/
tempFile = new File(Environment.getExternalStorageDirectory().
getAbsolutePath() + "/"+"image.jpg");
imageArray = new byte[(int)tempFile.length()];
try{
InputStream is = new FileInputStream(tempFile);
BufferedInputStream bis = new BufferedInputStream(is);
DataInputStream dis = new DataInputStream(bis);
int i = 0;
while (dis.available() > 0) {
imageArray[i] = dis.readByte();
i++;
}
dis.close();
} catch (Exception e) {
e.printStackTrace();
}
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inSampleSize = 5;
mBitmap = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length, bfo);
float w = mBitmap.getWidth();
float h = mBitmap.getHeight();
// construct our mesh
int index = 0;
for (int y = 0; y <= HEIGHT; y++) {
float fy = h * y / HEIGHT;
for (int x = 0; x <= WIDTH; x++) {
float fx = w * x / WIDTH;
setXY(mVerts, index, fx, fy);
setXY(mOrig, index, fx, fy);
index += 1;
}
}
mMatrix.setTranslate(10, 10);
mMatrix.invert(mInverse);
}
#Override protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFCCCCCC);
canvas.concat(mMatrix);
canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0,
null, 0, null);
}
private void warp(float cx, float cy) {
final float K = 10000;
float[] src = mOrig;
float[] dst = mVerts;
for (int i = 0; i < COUNT*2; i += 2) {
float x = src[i+0];
float y = src[i+1];
float dx = cx - x;
float dy = cy - y;
float dd = dx*dx + dy*dy;
float d = FloatMath.sqrt(dd);
float pull = K / (dd + 0.000001f);
pull /= (d + 0.000001f);
// android.util.Log.d("skia", "index " + i + " dist=" + d + " pull=" + pull);
if (pull >= 1) {
dst[i+0] = cx;
dst[i+1] = cy;
} else {
dst[i+0] = x + dx * pull;
dst[i+1] = y + dy * pull;
}
}
}
private int mLastWarpX = -9999; // don't match a touch coordinate
private int mLastWarpY;
#Override public boolean onTouchEvent(MotionEvent event) {
float[] pt = { event.getX(), event.getY() };
mInverse.mapPoints(pt);
int x = (int)pt[0];
int y = (int)pt[1];
if (mLastWarpX != x || mLastWarpY != y) {
mLastWarpX = x;
mLastWarpY = y;
warp(pt[0], pt[1]);
invalidate();
}
return true;
}
}
}