SurfaceView Returns black Screen in droidreader - android
I had tried alot & even search alot but i didn't found
the solution about the black screen
which i get by fetching the cache view on the surface view..
if is there any other way to capture the screen then let me know about this..
if i use another control & fetching the drawable cache of that control it also return null..
this is the code which i used to fetch the screen Image....
try {
// Button btn = new Button(mActivity.getApplicationContext());
view.buildDrawingCache();
view.setDrawingCacheEnabled(true);
Bitmap b = view.getDrawingCache();
b.compress(CompressFormat.JPEG, 100, new FileOutputStream(
"/mnt/sdcard/documents/" + new Date().getTime() + ".JPEG"));
} catch (Exception e) {
e.printStackTrace();
}
i had used this on the touch_up action of the surface view.....
EDIT:
public class DroidReaderActivity extends Activity {
private static final boolean LOG = false;
private static final int REQUEST_CODE_PICK_FILE = 1;
private static final int REQUEST_CODE_OPTION_DIALOG = 2;
private static final int DIALOG_GET_PASSWORD = 1;
private static final int DIALOG_ABOUT = 2;
private static final int DIALOG_GOTO_PAGE = 3;
private static final int DIALOG_WELCOME = 4;
private static final int DIALOG_ENTER_ZOOM = 5;
private static final String PREFERENCE_EULA_ACCEPTED = "eula.accepted";
private static final String PREFERENCES_EULA = "eula";
protected DroidReaderView mReaderView = null;
protected DroidReaderDocument mDocument = null;
protected Menu m_ZoomMenu;
FrameLayout fl;
private String mFilename;
private String mTemporaryFilename;
private String mPassword;
private int mPageNo;
private SQLiteDatabase db;
static DatabaseConnectionAPI db_api;
private boolean mDocumentIsOpen = false;
private boolean mLoadedDocument = false;
private boolean mWelcomeShown = false;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_PICK_FILE:
if (resultCode == RESULT_OK && data != null) {
// Theoretically there could be a case where OnCreate() is called
// again with the intent that was originally used to open the app,
// which would revert to a previous document. Use setIntent
// to update the intent that will be supplied back to OnCreate().
setIntent(data);
mTemporaryFilename = data.getDataString();
if (mTemporaryFilename != null) {
if (mTemporaryFilename.startsWith("file://")) {
mTemporaryFilename = mTemporaryFilename.substring(7);
}
mPassword = "";
openDocumentWithDecodeAndLookup();
}
}
break;
case REQUEST_CODE_OPTION_DIALOG:
readPreferences();
tryLoadLastFile();
break;
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("ONCREATE");
db_api = new DatabaseConnectionAPI(this);
try {
db_api.createDataBase();
db_api.openDataBase();
} catch (IOException e) {
e.printStackTrace();
}
// first, show the welcome if it hasn't been shown already:
final SharedPreferences preferences = getSharedPreferences(PREFERENCES_EULA, Context.MODE_PRIVATE);
if (!preferences.getBoolean(PREFERENCE_EULA_ACCEPTED, false)) {
mWelcomeShown = true;
preferences.edit().putBoolean(PREFERENCE_EULA_ACCEPTED, true).commit();
showDialog(DIALOG_WELCOME);
}
if (mDocument == null)
mDocument = new DroidReaderDocument();
// Initialize the PdfRender engine
PdfRender.setFontProvider(new DroidReaderFontProvider(this));
// then build our layout. it's so simple that we don't use
// XML for now.
fl = new FrameLayout(this);
mReaderView = new DroidReaderView(this, null, mDocument);
// add the viewing area and the navigation
fl.addView(mReaderView);
setContentView(fl);
readPreferences();
if (savedInstanceState != null) {
mFilename = savedInstanceState.getString("filename");
if ((new File(mFilename)).exists()) {
mPassword = savedInstanceState.getString("password");
mDocument.mZoom = savedInstanceState.getFloat("zoom");
mDocument.mRotation = savedInstanceState.getInt("rotation");
mPageNo = savedInstanceState.getInt("page");
mDocument.mMarginOffsetX = savedInstanceState.getInt("marginOffsetX");
mDocument.mMarginOffsetY = savedInstanceState.getInt("marginOffsetY");
mDocument.mContentFitMode = savedInstanceState.getInt("contentFitMode");
openDocument();
mLoadedDocument = true;
}
savedInstanceState.clear();
}
Timer mTimer = new Timer();
mTimer.schedule(new TimerTask() {
#Override
public void run() {
try {
Bitmap saveBitmap = Bitmap.createBitmap(fl.getWidth(), fl.getHeight(), Bitmap.Config.ARGB_8888);
saveBitmap.compress(CompressFormat.JPEG, 100,
new FileOutputStream("/mnt/sdcard/documents/" + new Date().getTime() + ".JPEG"));
} catch (Exception e) {
e.printStackTrace();
}
}
}, 4000);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if ((mDocument != null) && mDocument.isPageLoaded()) {
outState.putFloat("zoom", mDocument.mZoom);
outState.putInt("rotation", mDocument.mRotation);
outState.putInt("page", mDocument.mPage.no);
outState.putInt("offsetX", mDocument.mOffsetX);
outState.putInt("offsetY", mDocument.mOffsetY);
outState.putInt("marginOffsetX", mDocument.mMarginOffsetX);
outState.putInt("marginOffsetY", mDocument.mMarginOffsetY);
outState.putInt("contentFitMode", mDocument.mContentFitMode);
outState.putString("password", mPassword);
outState.putString("filename", mFilename);
mDocument.closeDocument();
}
}
public void onTap(float X, float Y) {
float left, right, top, bottom;
float width = mDocument.mDisplaySizeX;
float height = mDocument.mDisplaySizeY;
boolean prev = false;
boolean next = false;
if (mDocumentIsOpen) {
left = width * (float) 0.25;
right = width * (float) 0.75;
top = height * (float) 0.25;
bottom = height * (float) 0.75;
if ((X < left) && (Y < top))
prev = true;
if ((X < left) && (Y > bottom))
next = true;
if ((X > right) && (Y < top))
prev = true;
if ((X > right) && (Y > bottom))
next = true;
if ((X > left) && (X < right) && (Y > bottom)) {
Log.d("DroidReaderMetrics", String.format("Zoom = %5.2f%%", mDocument.mZoom * 100.0));
Log.d("DroidReaderMetrics", String.format("Page size = (%2.0f,%2.0f)", mDocument.mPage.mMediabox[2]
- mDocument.mPage.mMediabox[0], mDocument.mPage.mMediabox[3] - mDocument.mPage.mMediabox[1]));
Log.d("DroidReaderMetrics", String.format(
"Display size = (%d,%d)", mDocument.mDisplaySizeX, mDocument.mDisplaySizeY));
Log.d("DroidReaderMetrics", String.format("DPI = (%d, %d)", mDocument.mDpiX, mDocument.mDpiY));
Log.d("DroidReaderMetrics", String.format("Content size = (%2.0f,%2.0f)",
mDocument.mPage.mContentbox[2] - mDocument.mPage.mContentbox[0],
mDocument.mPage.mContentbox[3] - mDocument.mPage.mContentbox[1]));
Log.d("DroidReaderMetrics", String.format("Content offset = (%2.0f,%2.0f)",
mDocument.mPage.mContentbox[0], mDocument.mPage.mContentbox[1]));
Log.d("DroidReaderMetrics", String.format(
"Document offset = (%d,%d)", mDocument.mOffsetX, mDocument.mOffsetY));
}
if (next) {
if (mDocument.havePage(1, true))
openPage(1, true);
} else if (prev) {
if (mDocument.havePage(-1, true))
openPage(-1, true);
}
}
}
protected void openDocument() {
// Store the view details for the previous document and close it.
if (mDocumentIsOpen) {
mDocument.closeDocument();
mDocumentIsOpen = false;
}
try {
this.setTitle(mFilename);
mDocument.open(mFilename, mPassword, mPageNo);
openPage(0, true);
mDocumentIsOpen = true;
} catch (PasswordNeededException e) {
showDialog(DIALOG_GET_PASSWORD);
} catch (WrongPasswordException e) {
Toast.makeText(this, R.string.error_wrong_password, Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(this, R.string.error_opening_document, Toast.LENGTH_LONG).show();
}
}
protected void openDocumentWithDecodeAndLookup() {
try {
mTemporaryFilename = URLDecoder.decode(mTemporaryFilename, "utf-8");
// Do some sanity checks on the supplied filename.
File f = new File(mTemporaryFilename);
if ((f.exists()) && (f.isFile()) && (f.canRead())) {
mFilename = mTemporaryFilename;
openDocumentWithLookup();
} else {
Toast.makeText(this, R.string.error_file_open_failed, Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(this, R.string.error_opening_document, Toast.LENGTH_LONG).show();
}
}
protected void openDocumentWithLookup() {
readOrWriteDB(false);
openDocument();
}
protected void openPage(int no, boolean isRelative) {
try {
if (!(no == 0 && isRelative))
mDocument.openPage(no, isRelative);
this.setTitle(new File(mFilename).getName()
+ String.format(" (%d/%d)", mDocument.mPage.no, mDocument.mDocument.pagecount));
mPageNo = mDocument.mPage.no;
} catch (PageLoadException e) {
}
}
private void readPreferences() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
if (prefs.getString("zoom_type", "0").equals("0")) {
float zoom = Float.parseFloat(prefs.getString("zoom_percent", "50"));
if ((1 <= zoom) && (1000 >= zoom)) {
mDocument.setZoom(zoom / 100, false);
}
} else {
mDocument.setZoom(Float.parseFloat(prefs.getString("zoom_type", "0")), false);
}
if (prefs.getBoolean("dpi_auto", true)) {
// read the display's DPI
mDocument.setDpi((int) metrics.xdpi, (int) metrics.ydpi);
} else {
int dpi = Integer.parseInt(prefs.getString("dpi_manual", "160"));
if ((dpi < 1) || (dpi > 4096))
dpi = 160; // sanity check fallback
mDocument.setDpi(dpi, dpi);
}
if (prefs.getBoolean("tilesize_by_factor", true)) {
// set the tile size for rendering by factor
Float factor = Float.parseFloat(prefs.getString("tilesize_factor", "1.5"));
mDocument.setTileMax((int) (metrics.widthPixels * factor), (int) (metrics.heightPixels * factor));
} else {
int tilesize_x = Integer.parseInt(prefs.getString("tilesize_x", "640"));
int tilesize_y = Integer.parseInt(prefs.getString("tilesize_x", "480"));
if (metrics.widthPixels < metrics.heightPixels) {
mDocument.setTileMax(tilesize_x, tilesize_y);
} else {
mDocument.setTileMax(tilesize_y, tilesize_x);
}
}
boolean invert = prefs.getBoolean("invert_display", false);
mDocument.setDisplayInvert(invert);
mReaderView.setDisplayInvert(invert);
if (prefs.getBoolean("full_screen", false)) {
this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
mDocument.mHorizontalScrollLock = prefs.getBoolean("horizontal_scroll_lock", false);
}
protected void setZoom(float newZoom) {
newZoom = newZoom / (float) 100.0;
if (newZoom > 16.0)
newZoom = (float) 16.0;
if (newZoom < 0.0625)
newZoom = (float) 0.0625;
mDocument.setZoom(newZoom, false);
}
protected void tryLoadLastFile() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
mFilename = prefs.getString("last_open_file", "");
if (mFilename != null) {
if ((mFilename.length() > 0) && ((new File(mFilename)).exists())) {
// Don't URL-decode the filename, as that's presumably already been done.
mPassword = "";
openDocumentWithLookup();
mLoadedDocument = true;
}
}
}
}
DroidReaderView:
public class DroidReaderView extends SurfaceView implements OnGestureListener,
SurfaceHolder.Callback, DroidReaderDocument.RenderListener {
public static Path mPath = new Path();
private static StringBuffer sbx = new StringBuffer();
private static StringBuffer sby = new StringBuffer();
public static Paint mPaint = new Paint();
public static Paint nullpaint = new Paint();
private String sx, sy, sbx_str, sby_str;
public static Canvas mCanvas = new Canvas();
private int pid = 1;
/**
* Debug helper
*/
protected final static String TAG = "DroidReaderView";
protected final static boolean LOG = false;
/**
* our view thread which does the drawing
*/
public DroidReaderViewThread mThread;
/**
* our gesture detector
*/
protected final GestureDetector mGestureDetector;
/**
* our context
*/
protected final DroidReaderActivity mActivity;
/**
* our SurfaceHolder
*/
protected final SurfaceHolder mSurfaceHolder;
public static DroidReaderDocument mDocument;
protected boolean mDisplayInvert;
/**
* constructs a new View
*
* #param context
* Context for the View
* #param attrs
* attributes (may be null)
*/
public DroidReaderView(final DroidReaderActivity activity, AttributeSet attrs, DroidReaderDocument document) {
super(activity, attrs);
mActivity = activity;
mSurfaceHolder = getHolder();
mDocument = document;
mDocument.mRenderListener = this;
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
// tell the SurfaceHolder to inform this thread on
// changes to the surface
mSurfaceHolder.addCallback(this);
mGestureDetector = new GestureDetector(this);
}
/* event listeners: */
#Override
protected void onDraw(Canvas canvas) {
mThread.c = canvas;
mThread.c = mSurfaceHolder.lockCanvas();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mThread.c.drawPath(mPath, mPaint);
mSurfaceHolder.unlockCanvasAndPost(mThread.c);
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (LOG)
Log.d(TAG, "onFling(): notifying ViewThread");
mThread.mScroller.fling(0, 0, -(int) velocityX, -(int) velocityY, -4096, 4096, -4096, 4096);
mThread.triggerRepaint();
return true;
}
/* keyboard events: */
#Override
public boolean onKeyDown(int keyCode, KeyEvent msg) {
if (LOG)
Log.d(TAG, "onKeyDown(), keycode " + keyCode);
return false;
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent msg) {
if (LOG)
Log.d(TAG, "onKeyUp(), keycode " + keyCode);
return false;
}
/* interface for the GestureListener: */
#Override
public void onLongPress(MotionEvent e) {
if (LOG)
Log.d(TAG, "onLongPress(): ignoring!");
}
#Override
public void onNewRenderedPixmap() {
if (LOG)
Log.d(TAG, "new rendered pixmap was signalled");
mThread.triggerRepaint();
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (LOG)
Log.d(TAG, "onScroll(), distance vector: " + distanceX + "," + distanceY);
mDocument.offset((int) distanceX, (int) distanceY, true);
mThread.triggerRepaint();
return true;
}
#Override
public void onShowPress(MotionEvent e) {
if (LOG)
Log.d(TAG, "onShowPress(): ignoring!");
}
#Override
public boolean onSingleTapUp(MotionEvent e) {
// Pass the tap, and the window dimensions, to the activity to process.
mActivity.onTap(e.getX(), e.getY());
return true;
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.moveTo(x, y);
mX = x;
sx = Float.toString(mX);
sbx.append(sx);
sbx.append(",");
mY = y;
sy = Float.toString(mY);
sby.append(sy);
sby.append(",");
sbx_str = sbx.toString();
sby_str = sby.toString();
}
private void draw_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
sx = Float.toString(mX);
sbx.append(sx);
sbx.append(",");
mY = y;
sy = Float.toString(mY);
sby.append(sy);
sby.append(",");
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
sx = Float.toString(mX);
sbx.append(sx);
sbx.append(",");
sy = Float.toString(mY);
sby.append(sy);
sby.append(",");
mPath.reset();
sbx_str = sbx.toString().trim();
sby_str = sby.toString().trim();
insert(TAGS.presentation_id, mDocument.mPage.no, sbx_str, sby_str);
sbx = new StringBuffer();
sby = new StringBuffer();
System.out.println(sbx_str.trim());
System.out.println(sby_str.trim());
}
#Override
public boolean onTouchEvent(final MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
draw_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
try {
// Button btn = new Button(mActivity.getApplicationContext());
// buildDrawingCache();
// setDrawingCacheEnabled(true);
// Bitmap b = getDrawingCache();
// b.compress(CompressFormat.JPEG, 100, new FileOutputStream(
// "/mnt/sdcard/documents/" + new Date().getTime() + ".JPEG"));
} catch (Exception e) {
e.printStackTrace();
}
break;
}
invalidate();
if (LOG) {
Log.d(TAG, "onTouchEvent(): notifying mGestureDetector");
invalidate();
}
if (mGestureDetector.onTouchEvent(event)) {
invalidate();
return true;
}
return true;
}
#Override
public boolean onTrackballEvent(MotionEvent event) {
if (LOG)
Log.d(TAG, "onTouchEvent(): notifying ViewThread");
mDocument
.offset((int) event.getX() * 20, (int) event.getY() * 20, true);
mThread.triggerRepaint();
return true;
}
/* surface events: */
public void setDisplayInvert(boolean invert) {
if (mThread != null)
mThread.setPainters(invert);
mDisplayInvert = invert;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if (LOG)
Log.d(TAG, "surfaceChanged(): size " + width + "x" + height);
mDocument.startRendering(width, height);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (LOG)
Log.d(TAG, "surfaceCreated(): starting ViewThread");
mThread = new DroidReaderViewThread(holder, mActivity, mDocument);
mThread.setPainters(mDisplayInvert);
mThread.start();
}
/* render events */
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (LOG)
Log.d(TAG, "surfaceDestroyed(): dying");
mDocument.stopRendering();
boolean retry = true;
mThread.mRun = false;
mThread.interrupt();
while (retry) {
try {
mThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
#Override
public boolean onDown(MotionEvent e) {
return false;
}
DroidReaderViewThread :
Thread that cares for blitting Pixmaps onto the Canvas and handles scrolling
class DroidReaderViewThread extends Thread {
public Canvas c = new Canvas();
private Cursor mCursor;
private Path mPath1 = new Path();
private StringBuffer sbx_read, sby_read;
public static Paint mPaint2 = new Paint();
public static Paint mPaint3 = new Paint();
Path old_path = new Path();
/**
* Debug helper
*/
protected final static String TAG = "DroidReaderViewThread";
protected final static boolean LOG = false;
/**
* the SurfaceHolder for our Surface
*/
protected final SurfaceHolder mSurfaceHolder;
/**
* Paint for not (yet) rendered parts of the page
*/
protected final Paint mEmptyPaint;
/**
* Paint for filling the display when there is no PdfPage (yet)
*/
protected final Paint mNoPagePaint;
/**
* Paint for the status text
*/
protected final Paint mStatusPaint;
/**
* Flag that our thread should be running
*/
protected boolean mRun = true;
/**
* our scroller
*/
protected final Scroller mScroller;
protected final DroidReaderDocument mDocument;
/**
* Background render thread, using the SurfaceView programming scheme
*
* #param holder
* our SurfaceHolder
* #param context
* the Context for our drawing
*/
public DroidReaderViewThread(SurfaceHolder holder, Context context, DroidReaderDocument document) {
// store a reference to our SurfaceHolder
mSurfaceHolder = holder;
mDocument = document;
// initialize Paints for non-Pixmap areas
mEmptyPaint = new Paint();
mNoPagePaint = new Paint();
mStatusPaint = new Paint();
setPainters(false);
// the scroller, i.e. the object that calculates/interpolates
// positions for scrolling/jumping/flinging
mScroller = new Scroller(context);
}
/**
* ll this does the actual drawing to the Canvas for our surface
*/
private void doDraw() {
if (LOG)
Log.d(TAG, "drawing...");
c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
if (!mDocument.isPageLoaded()) {
// no page/document loaded
if (LOG)
Log.d(TAG, "no page loaded.");
c.drawRect(0, 0, c.getWidth(), c.getHeight(), mNoPagePaint);
} else if (mDocument.havePixmap()) {
// we have both page and Pixmap, so draw:
// background:
if (LOG)
Log.d(TAG, "page loaded, rendering pixmap");
c.drawRect(0, 0, c.getWidth(), c.getHeight(), mEmptyPaint);
Log.d("CALL", "CALL");
c.drawBitmap(mDocument.mView.mBuf, 0,
mDocument.mView.mViewBox.width(), -mDocument.mOffsetX + mDocument.mView.mViewBox.left,
-mDocument.mOffsetY + mDocument.mView.mViewBox.top,
mDocument.mView.mViewBox.width(), mDocument.mView.mViewBox.height(), false, null);
try {
Log.d("Reading", "Reading");
mCursor = DroidReaderActivity.db_api
.ExecuteQueryGetCursor("SELECT * FROM path WHERE page_no=" + mDocument.mPage.no
+ " AND presentation_id=" + TAGS.presentation_id + ";");
if (!mCursor.equals(null)) {
mCursor.moveToFirst();
float x1 = 0, y1 = 0;
int pid = 0;
do {
sbx_read = new StringBuffer();
sbx_read.append(mCursor.getString(mCursor.getColumnIndex("x_path")));
sby_read = new StringBuffer();
sby_read.append(mCursor.getString(mCursor.getColumnIndex("y_path")));
String[] sbx_read_array = sbx_read.toString().trim().split(",");
String[] sby_read_array = sby_read.toString().trim().split(",");
for (int i = 0; i < sbx_read_array.length; i++) {
x1 = Float.parseFloat(sbx_read_array[i].toString());
y1 = Float.parseFloat(sby_read_array[i].toString());
if (pid != mCursor.getInt(mCursor.getColumnIndex("path_id"))) {
pid = mCursor.getInt(mCursor.getColumnIndex("path_id"));
Log.d("New Path Id.",
String.valueOf(mCursor.getInt(mCursor.getColumnIndex("path_id"))));
mPath1.reset();
mPath1.moveTo(x1, y1);
} else {
Log.d("Path id repeating.",
String.valueOf(mCursor.getInt(mCursor.getColumnIndex("path_id"))));
}
mPath1.lineTo(x1, y1);
c.drawPath(mPath1, DroidReaderView.mPaint);
}
} while (mCursor.moveToNext());
mCursor.close();
Log.d("Read mode Complete", "Read mode Complete");
}
} catch (Exception e) {
// Log.d("read Cursor", e.getMessage().toString());
}
} else {
// page loaded, but no Pixmap yet
if (LOG)
Log.d(TAG, "page loaded, but no active Pixmap.");
c.drawRect(0, 0, c.getWidth(), c.getHeight(), mEmptyPaint);
mPaint3.setAntiAlias(true);
mPaint3.setDither(true);
mPaint3.setColor(Color.TRANSPARENT);
mPaint3.setStyle(Paint.Style.STROKE);
mPaint3.setStrokeJoin(Paint.Join.ROUND);
mPaint3.setStrokeCap(Paint.Cap.ROUND);
mPaint3.setStrokeWidth(12);
mPaint3.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
c.drawPath(old_path, mPaint3);
}
} finally {
if (c != null) {
mPaint2.setAntiAlias(true);
mPaint2.setDither(true);
mPaint2.setColor(Color.GREEN);
mPaint2.setStyle(Paint.Style.STROKE);
mPaint2.setStrokeJoin(Paint.Join.ROUND);
mPaint2.setStrokeCap(Paint.Cap.ROUND);
mPaint2.setStrokeWidth(12);
c.drawPath(DroidReaderView.mPath, mPaint2);
// DroidReaderView.mPath.reset();
// old_path = DroidReaderView.mPath;
}
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
/**
* Main Thread loop
*/
#SuppressWarnings("static-access")
#Override
public void run() {
while (mRun) {
boolean doSleep = true;
if (!mScroller.isFinished()) {
if (mScroller.computeScrollOffset()) {
if (LOG)
Log.d(TAG, "new scroll offset");
doSleep = false;
int oldX = mDocument.mOffsetX;
int oldY = mDocument.mOffsetY;
mDocument.offset(mScroller.getCurrX(), mScroller.getCurrY(), true);
if ((oldX == mDocument.mOffsetX) && (oldY == mDocument.mOffsetY))
mScroller.abortAnimation();
} else {
mScroller.abortAnimation();
}
}
doDraw();
// if we're allowed, we will go to sleep now
if (doSleep) {
try {
// nothing to do, wait for someone waking us up:
if (LOG)
Log.d(TAG, "ViewThread going to sleep");
// between
// the check for pending interrupts and the sleep() which
// could lead to a not-handled repaint request:
if (!this.interrupted())
Thread.sleep(3600000);
} catch (InterruptedException e) {
if (LOG)
Log.d(TAG, "ViewThread woken up");
}
}
}
// mRun is now false, so we shut down.
if (LOG)
Log.d(TAG, "shutting down");
}
public void setPainters(boolean invert) {
// initialize Paints for non-Pixmap areas
mEmptyPaint.setStyle(Paint.Style.FILL);
mNoPagePaint.setStyle(Paint.Style.FILL);
mStatusPaint.setStyle(Paint.Style.FILL);
if (invert)
mEmptyPaint.setColor(0xff000000); // black
else
mEmptyPaint.setColor(0xffc0c0c0); // light gray
if (invert)
mNoPagePaint.setColor(0xff000000); // black
else
mNoPagePaint.setColor(0xff303030); // dark gray
if (invert)
mStatusPaint.setColor(0xff000000); // black
else
mStatusPaint.setColor(0xff808080); // medium gray
}
public void triggerRepaint() {
if (LOG)
Log.d(TAG, "repaint triggered");
interrupt();
}
}
I am using this, and its works fine in my case,
Here imageFrame is FrameLayout, root view of my View which I want to save as bitmap..
Bitmap saveBitmap = Bitmap.createBitmap(imageFrame.getWidth(), imageFrame.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(saveBitmap);
imageFrame.draw(c);
Try replacing imageFrame with your view.
EDIT:
Date date = new Date();
File filename = new File(file.getAbsoluteFile(), "" + date.getTime() + ".jpg");
try
{
fOut = new FileOutputStream(filename);
saveBitmap.compress(Bitmap.CompressFormat.JPEG, 50, fOut);
try
{
fOut.flush();
fOut.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
EDIT 2:
private void doDraw() {
int w = WIDTH_PX, h = HEIGHT_PX;
BitmapConfig conf = Bitmap.Config.ARGB_8888; // see other conf types
Bitmap bmp = Bitmap.createBitmap(w, h, conf); // this creates a MUTABLE bitmap
c = new Canvas(bmp);
Related
Android Canvas error - error queuing buffer to SurfaceTexture
Does anyone have an idea what would cause the below error? queueBuffer: error queuing buffer to SurfaceTexture, -32 I'm using SurfaceTexture in my app. The above error occurs when I try to set as a livewallpaper Below is the code: public class ClockWallpaperService extends WallpaperService { private WallpaperEngine myEngine; public void onCreate() { super.onCreate(); } #Override public Engine onCreateEngine() { System.out.println("Service: onCreateEngine"); this.myEngine = new WallpaperEngine(); return myEngine; } public void onDestroy() { this.myEngine = null; super.onDestroy(); } private class WallpaperEngine extends Engine implements OnGestureListener, OnSharedPreferenceChangeListener { public Bitmap image1, backgroundImage; private ArrayList<Leaf> leafList; private Bitmap bitmap1; private Bitmap bitmap2; private Bitmap bitmap3; private Bitmap currentBackgroundBitmap; private Paint paint; private int count; private int heightOfCanvas; private int widthOfCanvas; private float touchX; private float touchY; private int interval; private int amount; private boolean fallingDown; private float bgX = 0; private String colorFlag; private String backgroundFlag; private Random rand; private GestureDetector detector; private static final int DRAW_MSG = 0; private static final int MAX_SIZE = 101; private Handler mHandler = new Handler() { public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case DRAW_MSG: drawPaper(); break; } } }; /** hands colors for hour, min, sec */ private int[] colors = { 0xFFFF0000, 0xFF0000FF, 0xFFA2BC13 }; // private int bgColor; private int width; private int height; private boolean visible = true; private boolean displayHandSec; private AnalogClock clock; private SharedPreferences prefs; WallpaperEngine() { // get the fish and background image references backgroundImage = BitmapFactory.decodeResource(getResources(), R.drawable.bg1); SharedPreferences sp = getSharedPreferences("back_position", Activity.MODE_PRIVATE); int position = sp.getInt("back_position", 1); Global.backgroundDial = BitmapFactory.decodeResource( getResources(), Global.BackgroundId[position]); prefs = PreferenceManager .getDefaultSharedPreferences(ClockWallpaperService.this); prefs.registerOnSharedPreferenceChangeListener(this); displayHandSec = prefs.getBoolean( SettingsActivity.DISPLAY_HAND_SEC_KEY, true); paint = new Paint(); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5); // bgColor = Color.parseColor("#C0C0C0"); clock = new AnalogClock(getApplicationContext()); } #Override public void onCreate(SurfaceHolder surfaceHolder) { // TODO Auto-generated method stub super.onCreate(surfaceHolder); System.out.println("Engine: onCreate"); this.leafList = new ArrayList<Leaf>(); this.bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.flower1); this.bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.flower2); this.bitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.flower3); this.paint = new Paint(); this.paint.setAntiAlias(true); this.count = -1; this.rand = new Random(); this.detector = new GestureDetector(this); this.touchX = -1.0f; this.touchY = -1.0f; SharedPreferences pref = PreferenceManager .getDefaultSharedPreferences(ClockWallpaperService.this); pref.registerOnSharedPreferenceChangeListener(this); String speedStr = pref.getString("leaf_falling_speed", "20"); String amountStr = pref.getString("leaf_number", "50"); this.interval = Integer.parseInt(speedStr); this.amount = Integer.parseInt(amountStr); this.colorFlag = pref.getString("leaf_color", "0"); this.backgroundFlag = pref.getString("paper_background", "0"); String directionFlag = pref.getString("leaf_moving_direction", "0"); if (directionFlag.equals("0")) { this.fallingDown = true; } else { this.fallingDown = false; } this.setTouchEventsEnabled(true); } #Override public void onDestroy() { // TODO Auto-generated method stub System.out.println("Engine: onDestroy"); this.mHandler.removeMessages(DRAW_MSG); PreferenceManager.getDefaultSharedPreferences( ClockWallpaperService.this) .unregisterOnSharedPreferenceChangeListener(this); super.onDestroy(); } #Override public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub this.width = width; this.height = height; super.onSurfaceChanged(holder, format, width, height); } #Override public void onSurfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub super.onSurfaceCreated(holder); System.out.println("Engine: onSurfaceCreate"); Canvas canvas = holder.lockCanvas(); this.heightOfCanvas = canvas.getHeight(); this.widthOfCanvas = canvas.getWidth(); System.out.println("Width = " + widthOfCanvas + ", Height = " + heightOfCanvas); holder.unlockCanvasAndPost(canvas); this.mHandler.sendEmptyMessage(DRAW_MSG); } #Override public void onSurfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub System.out.println("Engine: onSurfaceDestroyed"); this.mHandler.removeMessages(DRAW_MSG); if (this.currentBackgroundBitmap != null) { this.currentBackgroundBitmap.recycle(); this.currentBackgroundBitmap = null; } if (this.bitmap1 != null) { this.bitmap1.recycle(); this.bitmap1 = null; } if (this.bitmap2 != null) { this.bitmap2.recycle(); this.bitmap2 = null; } if (this.bitmap3 != null) { this.bitmap3.recycle(); this.bitmap3 = null; } super.onSurfaceDestroyed(holder); } #Override public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) { super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset); System.out.println("xPixelOffset: " + xPixelOffset + ", yPixelOffset: " + yPixelOffset); this.bgX = xPixelOffset; } private void drawPaper() { count++; if (count >= 10000) { count = 0; } if (count % 10 == 0) { if (this.leafList.size() < MAX_SIZE) { Leaf l = null; Bitmap temp = bitmap1; if (colorFlag.equals("0")) { int index = rand.nextInt(3) + 1; switch (index) { case 1: temp = bitmap1; break; case 2: temp = bitmap2; break; case 3: temp = bitmap3; break; default: temp = bitmap1; break; } } else if (colorFlag.equals("1")) { temp = bitmap1; } else if (colorFlag.equals("2")) { temp = bitmap2; } else if (colorFlag.equals("3")) { temp = bitmap3; } l = new Leaf(temp, this.heightOfCanvas, this.widthOfCanvas); this.leafList.add(l); } } SurfaceHolder holder = this.getSurfaceHolder(); Canvas canvas = holder.lockCanvas(); drawBackground(canvas); int size = Math.min(this.amount, this.leafList.size()); for (int i = 0; i < size; i++) { Leaf l = this.leafList.get(i); if (l.isTouched()) { l.handleTouched(touchX, touchY); } else { l.handleFalling(this.fallingDown); } l.drawLeaf(canvas, paint); } holder.unlockCanvasAndPost(canvas); this.mHandler.sendEmptyMessageDelayed(DRAW_MSG, this.interval); } private void drawBackground(Canvas c) { c.drawBitmap(backgroundImage, 0, 0, null); clock.config(width / 2, height / 2, (int) (width * 0.6f), new Date(), paint, colors, displayHandSec); clock.draw(c); } #Override public void onTouchEvent(MotionEvent event) { super.onTouchEvent(event); this.detector.onTouchEvent(event); } public boolean onDown(MotionEvent e) { touchX = e.getX(); touchY = e.getY(); int size = Math.min(this.amount, this.leafList.size()); for (int i = 0; i < size; i++) { Leaf l = this.leafList.get(i); float centerX = l.getX() + l.getBitmap().getWidth() / 2.0f; float centerY = l.getY() + l.getBitmap().getHeight() / 2.0f; if (!l.isTouched()) { if (Math.abs(centerX - touchX) <= 80 && Math.abs(centerY - touchY) <= 80 && centerX != touchX) { l.setTouched(true); } } } return true; } public void onShowPress(MotionEvent e) { } public boolean onSingleTapUp(MotionEvent e) { return false; } public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } public void onLongPress(MotionEvent e) { } public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } public void onSharedPreferenceChanged( SharedPreferences sharedPreferences, String key) { if (key.equals("leaf_falling_speed")) { String speedStr = sharedPreferences.getString(key, "20"); this.interval = Integer.parseInt(speedStr); } else if (key.equals("leaf_number")) { String amountStr = sharedPreferences.getString(key, "50"); this.amount = Integer.parseInt(amountStr); } else if (key.equals("leaf_moving_direction")) { String directionFlag = sharedPreferences.getString(key, "0"); if (directionFlag.equals("0")) { this.fallingDown = true; } else { this.fallingDown = false; } } else if (key.equals("leaf_color")) { this.colorFlag = sharedPreferences.getString(key, "0"); this.leafList.removeAll(leafList); } } } }
How to create an rectangle area when capturing ( camera )
I would like to achieve something like this: So the that the only thing you capture and process is the area in the rectangle. I need this because I want to do some OCR and I don't want the whole screen.
Maybe help you this source, (draw a bounding box on top of a camera preview to capture part of the image) Preview Camera Rectangle Code: Manifest: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.camera.preview" android:versionCode="1" android:versionName="1.0"> <application android:icon="#drawable/icon" android:label="#string/app_name"> <activity android:name=".CameraPreview" android:label="#string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="7" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> </manifest> Main.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <com.camera.preview.Preview android:id="#+id/preview" android:layout_width="fill_parent" android:layout_height="fill_parent" > </com.camera.preview.Preview> <com.camera.preview.TouchView android:id="#+id/left_top_view" android:layout_width="fill_parent" android:layout_height="fill_parent" > </com.camera.preview.TouchView> <ImageView android:id="#+id/startcamerapreview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:src="#drawable/camera" /> </RelativeLayout> CameraPreview: public class CameraPreview extends Activity implements SensorEventListener { private Preview mPreview; private ImageView mTakePicture; private TouchView mView; private boolean mAutoFocus = true; private boolean mFlashBoolean = false; private SensorManager mSensorManager; private Sensor mAccel; private boolean mInitialized = false; private float mLastX = 0; private float mLastY = 0; private float mLastZ = 0; private Rect rec = new Rect(); private int mScreenHeight; private int mScreenWidth; private boolean mInvalidate = false; private File mLocation = new File(Environment. getExternalStorageDirectory(),"test.jpg"); #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //Log.i(TAG, "onCreate()"); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // display our (only) XML layout - Views already ordered setContentView(R.layout.main); // the accelerometer is used for autofocus mSensorManager = (SensorManager) getSystemService(Context. SENSOR_SERVICE); mAccel = mSensorManager.getDefaultSensor(Sensor. TYPE_ACCELEROMETER); // get the window width and height to display buttons // according to device screen size DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); mScreenHeight = displaymetrics.heightPixels; mScreenWidth = displaymetrics.widthPixels; // I need to get the dimensions of this drawable to set margins // for the ImageView that is used to take pictures Drawable mButtonDrawable = this.getResources(). getDrawable(R.drawable.camera); mTakePicture = (ImageView) findViewById(R.id.startcamerapreview); // setting where I will draw the ImageView for taking pictures LayoutParams lp = new LayoutParams(mTakePicture.getLayoutParams()); lp.setMargins((int)((double)mScreenWidth*.85), (int)((double)mScreenHeight*.70) , (int)((double)mScreenWidth*.85)+mButtonDrawable. getMinimumWidth(), (int)((double)mScreenHeight*.70)+mButtonDrawable. getMinimumHeight()); mTakePicture.setLayoutParams(lp); // rec is used for onInterceptTouchEvent. I pass this from the // highest to lowest layer so that when this area of the screen // is pressed, it ignores the TouchView events and passes it to // this activity so that the button can be pressed. rec.set((int)((double)mScreenWidth*.85), (int)((double)mScreenHeight*.10) , (int)((double)mScreenWidth*.85)+mButtonDrawable.getMinimumWidth(), (int)((double)mScreenHeight*.70)+mButtonDrawable.getMinimumHeight()); mButtonDrawable = null; mTakePicture.setOnClickListener(previewListener); // get our Views from the XML layout mPreview = (Preview) findViewById(R.id.preview); mView = (TouchView) findViewById(R.id.left_top_view); mView.setRec(rec); } // this is the autofocus call back private AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback(){ public void onAutoFocus(boolean autoFocusSuccess, Camera arg1) { //Wait.oneSec(); mAutoFocus = true; }}; // with this I get the ratio between screen size and pixels // of the image so I can capture only the rectangular area of the // image and save it. public Double[] getRatio(){ Size s = mPreview.getCameraParameters().getPreviewSize(); double heightRatio = (double)s.height/(double)mScreenHeight; double widthRatio = (double)s.width/(double)mScreenWidth; Double[] ratio = {heightRatio,widthRatio}; return ratio; } // I am not using this in this example, but its there if you want // to turn on and off the flash. private OnClickListener flashListener = new OnClickListener(){ #Override public void onClick(View v) { if (mFlashBoolean){ mPreview.setFlash(false); } else{ mPreview.setFlash(true); } mFlashBoolean = !mFlashBoolean; } }; // This method takes the preview image, grabs the rectangular // part of the image selected by the bounding box and saves it. // A thread is needed to save the picture so not to hold the UI thread. private OnClickListener previewListener = new OnClickListener() { #Override public void onClick(View v) { if (mAutoFocus){ mAutoFocus = false; //mPreview.setCameraFocus(myAutoFocusCallback); Wait.oneSec(); Thread tGetPic = new Thread( new Runnable() { public void run() { Double[] ratio = getRatio(); int left = (int) (ratio[1]*(double)mView.getmLeftTopPosX()); // 0 is height int top = (int) (ratio[0]*(double)mView.getmLeftTopPosY()); int right = (int)(ratio[1]*(double)mView.getmRightBottomPosX()); int bottom = (int)(ratio[0]*(double)mView.getmRightBottomPosY()); savePhoto(mPreview.getPic(left,top,right,bottom)); mAutoFocus = true; } }); tGetPic.start(); } boolean pressed = false; if (!mTakePicture.isPressed()){ pressed = true; } } }; // just to close the app and release resources. #Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK){ finish(); } return super.onKeyDown(keyCode, event); } private boolean savePhoto(Bitmap bm) { FileOutputStream image = null; try { image = new FileOutputStream(mLocation); } catch (FileNotFoundException e) { e.printStackTrace(); } bm.compress(CompressFormat.JPEG, 100, image); if (bm != null) { int h = bm.getHeight(); int w = bm.getWidth(); //Log.i(TAG, "savePhoto(): Bitmap WxH is " + w + "x" + h); } else { //Log.i(TAG, "savePhoto(): Bitmap is null.."); return false; } return true; } public boolean onInterceptTouchEvent(MotionEvent ev) { final int action = ev.getAction(); boolean intercept = false; switch (action) { case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_DOWN: float x = ev.getX(); float y = ev.getY(); // here we intercept the button press and give it to this // activity so the button press can happen and we can take // a picture. if ((x >= rec.left) && (x <= rec.right) && (y>=rec.top) && (y<=rec.bottom)){ intercept = true; } break; } return intercept; } // mainly used for autofocus to happen when the user takes a picture // I also use it to redraw the canvas using the invalidate() method // when I need to redraw things. public void onSensorChanged(SensorEvent event) { if (mInvalidate == true){ mView.invalidate(); mInvalidate = false; } float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; if (!mInitialized){ mLastX = x; mLastY = y; mLastZ = z; mInitialized = true; } float deltaX = Math.abs(mLastX - x); float deltaY = Math.abs(mLastY - y); float deltaZ = Math.abs(mLastZ - z); if (deltaX > .5 && mAutoFocus){ //AUTOFOCUS (while it is not autofocusing) mAutoFocus = false; mPreview.setCameraFocus(myAutoFocusCallback); } if (deltaY > .5 && mAutoFocus){ //AUTOFOCUS (while it is not autofocusing) mAutoFocus = false; mPreview.setCameraFocus(myAutoFocusCallback); } if (deltaZ > .5 && mAutoFocus){ //AUTOFOCUS (while it is not autofocusing) */ mAutoFocus = false; mPreview.setCameraFocus(myAutoFocusCallback); } mLastX = x; mLastY = y; mLastZ = z; } // extra overrides to better understand app lifecycle and assist debugging #Override protected void onDestroy() { super.onDestroy(); //Log.i(TAG, "onDestroy()"); } #Override protected void onPause() { super.onPause(); //Log.i(TAG, "onPause()"); mSensorManager.unregisterListener(this); } #Override protected void onResume() { super.onResume(); mSensorManager.registerListener(this, mAccel, SensorManager.SENSOR_DELAY_UI); //Log.i(TAG, "onResume()"); } #Override protected void onRestart() { super.onRestart(); //Log.i(TAG, "onRestart()"); } #Override protected void onStop() { super.onStop(); //Log.i(TAG, "onStop()"); } #Override protected void onStart() { super.onStart(); //Log.i(TAG, "onStart()"); } public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub } } Preview: class Preview extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private Camera mCamera; private Camera.Parameters mParameters; private byte[] mBuffer; // this constructor used when requested as an XML resource public Preview(Context context, AttributeSet attrs) { super(context, attrs); init(); } public Preview(Context context) { super(context); init(); } public void init() { // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. mHolder = getHolder(); mHolder.addCallback(this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public Bitmap getPic(int x, int y, int width, int height) { System.gc(); Bitmap b = null; Size s = mParameters.getPreviewSize(); YuvImage yuvimage = new YuvImage(mBuffer, ImageFormat.NV21, s.width, s.height, null); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); yuvimage.compressToJpeg(new Rect(x, y, width, height), 100, outStream); // make JPG b = BitmapFactory.decodeByteArray(outStream.toByteArray(), 0, outStream.size()); // decode JPG if (b != null) { //Log.i(TAG, "getPic() WxH:" + b.getWidth() + "x" + b.getHeight()); } else { //Log.i(TAG, "getPic(): Bitmap is null.."); } yuvimage = null; outStream = null; System.gc(); return b; } private void updateBufferSize() { mBuffer = null; System.gc(); // prepare a buffer for copying preview data to int h = mCamera.getParameters().getPreviewSize().height; int w = mCamera.getParameters().getPreviewSize().width; int bitsPerPixel = ImageFormat.getBitsPerPixel(mCamera.getParameters().getPreviewFormat()); mBuffer = new byte[w * h * bitsPerPixel / 8]; //Log.i("surfaceCreated", "buffer length is " + mBuffer.length + " bytes"); } public void surfaceCreated(SurfaceHolder holder) { // The Surface has been created, acquire the camera and tell it where to draw. try { mCamera = Camera.open(); // WARNING: without permission in Manifest.xml, crashes } catch (RuntimeException exception) { //Log.i(TAG, "Exception on Camera.open(): " + exception.toString()); Toast.makeText(getContext(), "Camera broken, quitting :(",Toast.LENGTH_LONG).show(); // TODO: exit program } try { mCamera.setPreviewDisplay(holder); updateBufferSize(); mCamera.addCallbackBuffer(mBuffer); // where we'll store the image data mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() { public synchronized void onPreviewFrame(byte[] data, Camera c) { if (mCamera != null) { // there was a race condition when onStop() was called.. mCamera.addCallbackBuffer(mBuffer); // it was consumed by the call, add it back } } }); } catch (Exception exception) { //Log.e(TAG, "Exception trying to set preview"); if (mCamera != null){ mCamera.release(); mCamera = null; } // TODO: add more exception handling logic here } } public void surfaceDestroyed(SurfaceHolder holder) { // Surface will be destroyed when we return, so stop the preview. // Because the CameraDevice object is not a shared resource, it's very // important to release it when the activity is paused. //Log.i(TAG,"SurfaceDestroyed being called"); mCamera.stopPreview(); mCamera.release(); mCamera = null; } // FYI: not called for each frame of the camera preview // gets called on my phone when keyboard is slid out // requesting landscape orientation prevents this from being called as camera tilts public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { //Log.i(TAG, "Preview: surfaceChanged() - size now " + w + "x" + h); // Now that the size is known, set up the camera parameters and begin // the preview. try { mParameters = mCamera.getParameters(); mParameters.set("orientation","landscape"); for (Integer i : mParameters.getSupportedPreviewFormats()) { //Log.i(TAG, "supported preview format: " + i); } List<Size> sizes = mParameters.getSupportedPreviewSizes(); for (Size size : sizes) { //Log.i(TAG, "supported preview size: " + size.width + "x" + size.height); } mCamera.setParameters(mParameters); // apply the changes } catch (Exception e) { // older phone - doesn't support these calls } updateBufferSize(); // then use them to calculate Size p = mCamera.getParameters().getPreviewSize(); //Log.i(TAG, "Preview: checking it was set: " + p.width + "x" + p.height); // DEBUG mCamera.startPreview(); } public Parameters getCameraParameters(){ return mCamera.getParameters(); } public void setCameraFocus(AutoFocusCallback autoFocus){ if (mCamera.getParameters().getFocusMode().equals(mCamera.getParameters().FOCUS_MODE_AUTO) || mCamera.getParameters().getFocusMode().equals(mCamera.getParameters().FOCUS_MODE_MACRO)){ mCamera.autoFocus(autoFocus); } } public void setFlash(boolean flash){ if (flash){ mParameters.setFlashMode(Parameters.FLASH_MODE_TORCH); mCamera.setParameters(mParameters); } else{ mParameters.setFlashMode(Parameters.FLASH_MODE_OFF); mCamera.setParameters(mParameters); } } } TouchView: public class TouchView extends View { //private final String TAG = "TESTTESTTESTESTTESTESTEST"; private Drawable mLeftTopIcon; private Drawable mRightTopIcon; private Drawable mLeftBottomIcon; private Drawable mRightBottomIcon; private boolean mLeftTopBool = false; private boolean mRightTopBool = false; private boolean mLeftBottomBool = false; private boolean mRightBottomBool = false; // Starting positions of the bounding box private float mLeftTopPosX = 30; private float mLeftTopPosY = 120; private float mRightTopPosX = 150; private float mRightTopPosY = 120; private float mLeftBottomPosX = 30; private float mLeftBottomPosY = 200; private float mRightBottomPosX = 150; private float mRightBottomPosY = 200; private float mPosX; private float mPosY; private float mLastTouchX; private float mLastTouchY; private Paint topLine; private Paint bottomLine; private Paint leftLine; private Paint rightLine; private Rect buttonRec; private int mCenter; private static final int INVALID_POINTER_ID = -1; private int mActivePointerId = INVALID_POINTER_ID; // you can ignore this private ScaleGestureDetector mScaleDetector; private float mScaleFactor = 1.f; public TouchView(Context context){ super(context); init(context); } public TouchView(Context context, AttributeSet attrs){ super (context,attrs); init(context); } public TouchView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } private void init(Context context) { // I need to create lines for the bouding box to connect topLine = new Paint(); bottomLine = new Paint(); leftLine = new Paint(); rightLine = new Paint(); setLineParameters(Color.WHITE,2); // Here I grab the image that will work as the corners of the bounding // box and set their positions. mLeftTopIcon = context.getResources().getDrawable(R.drawable.corners); mCenter = mLeftTopIcon.getMinimumHeight()/2; mLeftTopIcon.setBounds((int)mLeftTopPosX, (int)mLeftTopPosY, mLeftTopIcon.getIntrinsicWidth()+(int)mLeftTopPosX, mLeftTopIcon.getIntrinsicHeight()+(int)mLeftTopPosY); mRightTopIcon = context.getResources().getDrawable(R.drawable.corners); mRightTopIcon.setBounds((int)mRightTopPosX, (int)mRightTopPosY, mRightTopIcon.getIntrinsicWidth()+(int)mRightTopPosX, mRightTopIcon.getIntrinsicHeight()+(int)mRightTopPosY); mLeftBottomIcon = context.getResources().getDrawable(R.drawable.corners); mLeftBottomIcon.setBounds((int)mLeftBottomPosX, (int)mLeftBottomPosY, mLeftBottomIcon.getIntrinsicWidth()+(int)mLeftBottomPosX, mLeftBottomIcon.getIntrinsicHeight()+(int)mLeftBottomPosY); mRightBottomIcon = context.getResources().getDrawable(R.drawable.corners); mRightBottomIcon.setBounds((int)mRightBottomPosX, (int)mRightBottomPosY, mRightBottomIcon.getIntrinsicWidth()+(int)mRightBottomPosX, mRightBottomIcon.getIntrinsicHeight()+(int)mRightBottomPosY); // Create our ScaleGestureDetector mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); } private void setLineParameters(int color, float width){ topLine.setColor(color); topLine.setStrokeWidth(width); bottomLine.setColor(color); bottomLine.setStrokeWidth(width); leftLine.setColor(color); leftLine.setStrokeWidth(width); rightLine.setColor(color); rightLine.setStrokeWidth(width); } // Draws the bounding box on the canvas. Every time invalidate() is called // this onDraw method is called. public void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); canvas.drawLine(mLeftTopPosX+mCenter, mLeftTopPosY+mCenter, mRightTopPosX+mCenter, mRightTopPosY+mCenter, topLine); canvas.drawLine(mLeftBottomPosX+mCenter, mLeftBottomPosY+mCenter, mRightBottomPosX+mCenter, mRightBottomPosY+mCenter, bottomLine); canvas.drawLine(mLeftTopPosX+mCenter,mLeftTopPosY+mCenter, mLeftBottomPosX+mCenter,mLeftBottomPosY+mCenter,leftLine); canvas.drawLine(mRightTopPosX+mCenter,mRightTopPosY+mCenter, mRightBottomPosX+mCenter,mRightBottomPosY+mCenter,rightLine); mLeftTopIcon.setBounds((int)mLeftTopPosX, (int)mLeftTopPosY, mLeftTopIcon.getIntrinsicWidth()+(int)mLeftTopPosX, mLeftTopIcon.getIntrinsicHeight()+(int)mLeftTopPosY); mRightTopIcon.setBounds((int)mRightTopPosX, (int)mRightTopPosY, mRightTopIcon.getIntrinsicWidth()+(int)mRightTopPosX, mRightTopIcon.getIntrinsicHeight()+(int)mRightTopPosY); mLeftBottomIcon.setBounds((int)mLeftBottomPosX, (int)mLeftBottomPosY, mLeftBottomIcon.getIntrinsicWidth()+(int)mLeftBottomPosX, mLeftBottomIcon.getIntrinsicHeight()+(int)mLeftBottomPosY); mRightBottomIcon.setBounds((int)mRightBottomPosX, (int)mRightBottomPosY, mRightBottomIcon.getIntrinsicWidth()+(int)mRightBottomPosX, mRightBottomIcon.getIntrinsicHeight()+(int)mRightBottomPosY); mLeftTopIcon.draw(canvas); mRightTopIcon.draw(canvas); mLeftBottomIcon.draw(canvas); mRightBottomIcon.draw(canvas); canvas.restore(); } public boolean onTouchEvent(MotionEvent ev) { final int action = ev.getAction(); boolean intercept = true; switch (action) { case MotionEvent.ACTION_DOWN: { final float x = ev.getX(); final float y = ev.getY(); // in CameraPreview we have Rect rec. This is passed here to return // a false when the camera button is pressed so that this view ignores // the touch event. if ((x >= buttonRec.left) && (x <=buttonRec.right) && (y>=buttonRec.top) && (y<=buttonRec.bottom)){ intercept = false; break; } // is explained below, when we get to this method. manhattanDistance(x,y); // Remember where we started mLastTouchX = x; mLastTouchY = y; mActivePointerId = ev.getPointerId(0); break; } case MotionEvent.ACTION_MOVE: { final int pointerIndex = ev.findPointerIndex(mActivePointerId); final float x = ev.getX(); final float y = ev.getY(); //Log.i(TAG,"x: "+x); //Log.i(TAG,"y: "+y); // Only move if the ScaleGestureDetector isn't processing a gesture. // but we ignore here because we are not using ScaleGestureDetector. if (!mScaleDetector.isInProgress()) { final float dx = x - mLastTouchX; final float dy = y - mLastTouchY; mPosX += dx; mPosY += dy; invalidate(); } // Calculate the distance moved final float dx = x - mLastTouchX; final float dy = y - mLastTouchY; // Move the object if (mPosX >= 0 && mPosX <=800){ mPosX += dx; } if (mPosY >=0 && mPosY <= 480){ mPosY += dy; } // while its being pressed n it does not overlap the bottom line or right line if (mLeftTopBool && ((y+mCenter*2) < mLeftBottomPosY) && ((x+mCenter*2) < mRightTopPosX)){ if (dy != 0){ mRightTopPosY = y; } if (dx != 0){ mLeftBottomPosX = x; } mLeftTopPosX = x;//mPosX; mLeftTopPosY = y;//mPosY; } if (mRightTopBool && ((y+mCenter*2) < mRightBottomPosY) && (x > (mLeftTopPosX+mCenter*2))){ if (dy != 0){ mLeftTopPosY = y; } if (dx != 0){ mRightBottomPosX = x; } mRightTopPosX = x;//mPosX; mRightTopPosY = y;//mPosY; } if (mLeftBottomBool && (y > (mLeftTopPosY+mCenter*2)) && ((x +mCenter*2) < mRightBottomPosX)){ if (dx != 0){ mLeftTopPosX = x; } if (dy != 0){ mRightBottomPosY = y; } mLeftBottomPosX = x; mLeftBottomPosY = y; } if (mRightBottomBool && (y > (mLeftTopPosY+mCenter*2)) && (x > (mLeftBottomPosX+mCenter*2) )){ if (dx != 0){ mRightTopPosX = x; } if (dy != 0){ mLeftBottomPosY = y; } mRightBottomPosX = x; mRightBottomPosY = y; } // Remember this touch position for the next move event mLastTouchX = x; mLastTouchY = y; // Invalidate to request a redraw invalidate(); break; } case MotionEvent.ACTION_UP: { // when one of these is true, that means it can move when onDraw is called mLeftTopBool = false; mRightTopBool = false; mLeftBottomBool = false; mRightBottomBool = false; //mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_CANCEL: { mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_POINTER_UP: { // Extract the index of the pointer that left the touch sensor final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int pointerId = ev.getPointerId(pointerIndex); if (pointerId == mActivePointerId) { // This was our active pointer going up. Choose a new // active pointer and adjust accordingly. final int newPointerIndex = pointerIndex == 0 ? 1 : 0; mLastTouchX = ev.getX(newPointerIndex); mLastTouchY = ev.getY(newPointerIndex); mActivePointerId = ev.getPointerId(newPointerIndex); } break; } } return intercept; } // Where the screen is pressed, calculate the distance closest to one of the 4 corners // so that it can get the pressed and moved. Only 1 at a time can be moved. private void manhattanDistance(float x, float y) { double leftTopMan = Math.sqrt(Math.pow((Math.abs((double)x-(double)mLeftTopPosX)),2) + Math.pow((Math.abs((double)y-(double)mLeftTopPosY)),2)); double rightTopMan = Math.sqrt(Math.pow((Math.abs((double)x-(double)mRightTopPosX)),2) + Math.pow((Math.abs((double)y-(double)mRightTopPosY)),2)); double leftBottomMan = Math.sqrt(Math.pow((Math.abs((double)x-(double)mLeftBottomPosX)),2) + Math.pow((Math.abs((double)y-(double)mLeftBottomPosY)),2)); double rightBottomMan = Math.sqrt(Math.pow((Math.abs((double)x-(double)mRightBottomPosX)),2) + Math.pow((Math.abs((double)y-(double)mRightBottomPosY)),2)); //Log.i(TAG,"leftTopMan: "+leftTopMan); //Log.i(TAG,"RightTopMan: "+rightTopMan); if (leftTopMan < 50){ mLeftTopBool = true; mRightTopBool = false; mLeftBottomBool = false; mRightBottomBool = false; } else if (rightTopMan < 50){ mLeftTopBool = false; mRightTopBool = true; mLeftBottomBool = false; mRightBottomBool = false; } else if (leftBottomMan < 50){ mLeftTopBool = false; mRightTopBool = false; mLeftBottomBool = true; mRightBottomBool = false; } else if (rightBottomMan < 50){ mLeftTopBool = false; mRightTopBool = false; mLeftBottomBool = false; mRightBottomBool = true; } } private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { #Override public boolean onScale(ScaleGestureDetector detector) { mScaleFactor *= detector.getScaleFactor(); // Don't let the object get too small or too large. mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f)); invalidate(); return true; } } public float getmLeftTopPosX(){ return mLeftTopPosX; } public float getmLeftTopPosY(){ return mLeftTopPosY; } public float getmRightTopPosX(){ return mRightTopPosX; } public float getmRightTopPosY(){ return mRightTopPosY; } public float getmLeftBottomPosX() { return mLeftBottomPosX; } public float getmLeftBottomPosY() { return mLeftBottomPosY; } public float getmRightBottomPosY() { return mRightBottomPosY; } public float getmRightBottomPosX() { return mRightBottomPosX; } public void setRec(Rect rec) { this.buttonRec = rec; } // calls the onDraw method, I used it in my app Translanguage OCR // because I have a thread that needs to invalidate, or redraw // you cannot call onDraw from a thread not the UI thread. public void setInvalidate() { invalidate(); } } Wait: public class Wait { public static void oneSec() { try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } public static void manySec(long s) { try { Thread.currentThread().sleep(s * 1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
Adding zoom functionality to jPCT scene
I would like to add zoom functionality to my scene. How would one do that? This is my code at the moment: private static float touchTurn = 0; private static float touchTurnUp = 0; private static float xpos = -1; private static float ypos = -1; static class ClearGLSurfaceView extends GLSurfaceView { public ClearGLSurfaceView(Context context) { super(myContext); } #Override public boolean onTouchEvent(MotionEvent me) { if (me.getAction() == MotionEvent.ACTION_DOWN) { xpos = me.getX(); ypos = me.getY(); return true; } if (me.getAction() == MotionEvent.ACTION_UP) { xpos = -1; ypos = -1; touchTurn = 0; touchTurnUp = 0; return true; } if (me.getAction() == MotionEvent.ACTION_MOVE) { float xd = me.getX() - xpos; float yd = me.getY() - ypos; xpos = me.getX(); ypos = me.getY(); touchTurn = xd / 100f; touchTurnUp = yd / 100f; return true; } try { Thread.sleep(15); } catch (Exception e) { // Doesn't matter here... } return super.onTouchEvent(me); } } static class MyRenderer implements GLSurfaceView.Renderer { private long time = System.currentTimeMillis(); public MyRenderer() { } public void onSurfaceChanged(GL10 gl, int w, int h) { if (fb != null) { fb.dispose(); } fb = new FrameBuffer(gl, w, h); if (master == null) { world = new World(); world.setAmbientLight(20, 20, 20); sun = new Light(world); sun.setIntensity(250, 250, 250); try { cube = loadModel(thingName, thingScale); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } cube.build(); world.addObject(cube); Camera cam = world.getCamera(); cam.moveCamera(Camera.CAMERA_MOVEOUT, 50); cam.lookAt(cube.getTransformedCenter()); SimpleVector sv = new SimpleVector(); sv.set(cube.getTransformedCenter()); sv.y -= 100; sv.z -= 100; sun.setPosition(sv); MemoryHelper.compact(); if (master == null) { Logger.log("Saving master Activity!"); // master = fr; } } } public void onSurfaceCreated(GL10 gl, EGLConfig config) { } public void onDrawFrame(GL10 gl) { if (touchTurn != 0) { cube.rotateY(touchTurn); touchTurn = 0; } if (touchTurnUp != 0) { cube.rotateX(touchTurnUp); touchTurnUp = 0; } fb.clear(back); world.renderScene(fb); world.draw(fb); fb.display(); if (System.currentTimeMillis() - time >= 1000) { Logger.log(fps + "fps"); fps = 0; time = System.currentTimeMillis(); } fps++; } If you need more information let me know.
You can increase/decrease camera's fov.
Android game in surfaceview lagg spikes
guys. I'm playing around with making my very first Android game, but stumbled into a problem. The framerate seems to have random lag spikes. If I comment the background(s) out the framerate gets much smoother. I've looked around SO and can't find anything to solve my problems. I have a feeling it has something to do with allocating a specific amount of time every time I draw, but I don't know how to properly implement such a feature. Any suggestions? Btw, tryed hardware ac, anti etc. This is the class that starts the surfaceview : package com.example.glassrunner; Imports Here public class Game extends Activity { MySurfaceView mySurfaceView; public SoundPool spool; private int soundID; int length=0; /** Called when the activity is first created. */ #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); this.setVolumeControlStream(AudioManager.STREAM_MUSIC); mySurfaceView = new MySurfaceView(this); setContentView(mySurfaceView); } #Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); mySurfaceView.onResumeMySurfaceView(); } #Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); mySurfaceView.onPauseMySurfaceView(); } #Override protected void onDestroy() { super.onDestroy(); mySurfaceView = null; } } This is the surfaceview class : package com.example.glassrunner; Imports here public class MySurfaceView extends SurfaceView implements Runnable { public static boolean gameOver = false; SurfaceHolder surfaceHolder; Thread thread = null; public Integer score=0; public SoundPool spool; private int soundID; int length=0; public static MediaPlayer mp; volatile boolean running = false; int Yposition = 450; int Xposition = 50; Paint textPaint; long mLastTime; Bitmap background; Bitmap background2; Bitmap lines; Bitmap runSprite; Bitmap box; Paint bitmapPaint ; Paint textPaint2; Bitmap scaledBackground ; Bitmap scaledBackground2 ; Bitmap scaledLines ; Bitmap scaledBox; Canvas canvas; Paint paint; int SpX=0; int SpY=0; Bitmap[][] sprite; /** Variables for the counter */ int frameSamplesCollected = 0; int frameSampleTime = 0; int fps = 0; int speed = 5; Toast GameOverToast; Context context; MediaPlayer mMediaPlayer; public MySurfaceView(Context context) { super(context); this.context = context; // TODO Auto-generated constructor stub surfaceHolder = getHolder(); surfaceHolder.setFormat(PixelFormat.RGB_565); CharSequence text = "Game Over!"; int duration = Toast.LENGTH_SHORT; GameOverToast = Toast.makeText(context, text, duration); spool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0); soundID = spool.load(context, R.raw.jump, 1); mp = MediaPlayer.create(context, R.raw.saturdaymorningfunk); initialization(); } public void initialization() { mp.setLooping(true); mp.start(); Options options = new Options(); options.inSampleSize = 1/4; options.inPreferredConfig = Bitmap.Config.RGB_565; background=BitmapFactory.decodeResource(getResources(),R.drawable.background,options); lines=BitmapFactory.decodeResource(getResources(),R.drawable.lines);// getting the png from drawable folder background2=BitmapFactory.decodeResource(getResources(),R.drawable.background2,options); runSprite=BitmapFactory.decodeResource(getResources(),R.drawable.runsprite); box=BitmapFactory.decodeResource(getResources(),R.drawable.box); bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // tool for painting on the canvas bitmapPaint.setAntiAlias(true); bitmapPaint.setFilterBitmap(true); textPaint = new Paint(); textPaint.setColor(Color.RED); textPaint.setTextSize(32); textPaint2 = new Paint(); textPaint2.setColor(Color.BLUE); textPaint2.setTextSize(50); scaledBackground = Bitmap.createScaledBitmap(background, 2560, 500, true); scaledBackground2 = Bitmap.createScaledBitmap(background2, 2560, 400, true); scaledLines = Bitmap.createScaledBitmap(lines, 2560, 30, true); runSprite = Bitmap.createScaledBitmap(runSprite, 1400, 1000, true); scaledBox = Bitmap.createScaledBitmap(box, 100, 100, true); sprite = new Bitmap[4][7]; for(int row=0;row<=3;row++) { for(int col=0;col<=6;col++) { sprite[row][col] = Bitmap.createBitmap(runSprite, SpX, SpY, 200, 250); SpX+=200; } SpX=0; SpY+=250; } } public void onResumeMySurfaceView() { mp.seekTo(length); mp.start(); running = true; thread = new Thread(this); thread.start(); } public void onPauseMySurfaceView() { mp.pause(); length=mp.getCurrentPosition(); boolean retry = true; running = false; while(retry){ try { thread.join(); retry = false; } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void onDestroyMySurfaceView() { mp.stop(); running = false; thread = null; thread.stop(); } private void fps() { long now = System.currentTimeMillis(); if (mLastTime != 0) { //Time difference between now and last time we were here int time = (int) (now - mLastTime); frameSampleTime += time; frameSamplesCollected++; //After 10 frames if (frameSamplesCollected == 10) { //Update the fps variable fps = (int) (10000 / frameSampleTime); //Reset the sampletime + frames collected frameSampleTime = 0; frameSamplesCollected = 0; } } mLastTime = now; } public boolean pressDown = false; public long pressTime; public boolean onTouchEvent(MotionEvent event) { if (event != null) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if(Yposition == orgPos) { spool.play(soundID, 15, 15, 1, 0, 1f); pressDown = true; pressTime = System.currentTimeMillis(); } }else if (event.getAction() == MotionEvent.ACTION_UP) { pressDown = false; } } return true; } int x=0; int y=100; int x2=0; int y2=20; int row=0; int col=0; int limit = 100; int orgPos = 450; int Xbox = 1280; int Ybox = 580; Random r = new Random(); int RBox; public static String Fscore; boolean onTop = false; long now; long start; long stop; long time ; int spritePosition = 0 ; int spriteSize; #Override public void run() { while(running) { canvas = null; if(surfaceHolder.getSurface().isValid()) { canvas = surfaceHolder.lockCanvas(); fps(); // fps // Update screen parameters update(); draw(); surfaceHolder.unlockCanvasAndPost(canvas); } } } public void update() { if(score<500) { speed = 7; } else if(score%500 == 0) { speed = 7 + (score / 500); } if(col==6) { row++; col=0; } if(row==4) { row=0; } score++; Fscore = score.toString(); if(x>-1280) { x-=speed; }else if(x<=-1280) { x=0; } if(x2>-1280) { x2-=5; }else if(x2<=-1280) { x2=-0; } RBox = r.nextInt(999)+1280; if(Xbox > -100) { Xbox-=speed; }else if(Xbox<=-100) { Xbox=RBox; } if( (Xposition + 200 == Xbox +40 )&&(Yposition + 250 > Ybox+20)||( Xposition+200<=Xbox+70)&&( Xposition+200>=Xbox+20)&&(Yposition + 250 > Ybox+30) ) // collision { GameOverToast.show(); running = false; spool.release(); mp.release(); Looper.prepare(); Intent database = new Intent(context, MainHighscore.class); database.putExtra("score", Fscore); context.startActivity(database); onDestroyMySurfaceView(); } now = System.currentTimeMillis(); if(( now - pressTime) <= 600) { if(Yposition > limit) { Yposition -= 10; } } onTop = false; if((now - pressTime) >= 600 && (now - pressTime) <= 1200) { if(!(Yposition == orgPos)) { if(Yposition+250 >= Ybox && Xposition+200>=Xbox+70 && Xposition <= Xbox+40) { onTop=true; Yposition = 340; }else { Yposition += 10; } } } if((now - pressTime) >= 1200) { if(Yposition < 450) Yposition +=10; else Yposition = 450; } } public void draw() { canvas.drawColor(Color.WHITE); //canvas.drawBitmap(scaledBackground, x2,y2, bitmapPaint); canvas.drawBitmap(scaledBackground2, x,y, bitmapPaint); canvas.drawBitmap(scaledLines, x,650, bitmapPaint); canvas.drawText(Fscore, 1050, 50, textPaint2); canvas.drawText(fps + " fps", getWidth() / 2, getHeight() / 2, textPaint); canvas.drawBitmap(sprite[row][col],Xposition,Yposition,bitmapPaint ); canvas.drawBitmap(scaledBox,Xbox,Ybox,bitmapPaint); col++; } }
I think your problem might be actually the moving part. Your just drawing too much stuff, and the surfaceView is not meant for that.
Ontouch() isn't work with custom view?
I have a class it extends "View" and Implement "OnTouchListener" so it's will override ontouch method automatically but this method not work. I try to debug by put breakpoint in this method but it isn't called. I try to this problem from another forums. they tell that onTouch() must return true; But it's not better. my class problem : public class Viewer extends View implements OnTouchListener{ /** Constant tile width. */ public static final int TILEW = 32; /** Constant tile height. */ public static final int TILEH = 70; /** Constant tile shift due to increased level. */ public static final int TILESKEW = 7; /** Tile images. */ private Bitmap[][] tileImages; /** Highlighted tile images. */ private Bitmap[][] tileImagesHL; /** Board itself. */ private Board b; private Tile[][][] tTile; private float screenWidth = Defines.getScreenWidth(); private float screenHeight = Defines.getScreenHeight(); private float offsetImg = Defines.getOffsetImage(); private float reScalePosX = Defines.getReScalePosX(); private float reScalePosY = Defines.getReScalePosY(); private boolean firstIter; /** Stores selected tiles */ private ArrayList<Tile> selectedTiles;// = new ArrayList<Tile>(); /** Stores highlighted tiles by Hint */ private ArrayList<Tile> highlightedTiles;// = new ArrayList<Tile>(); ////////////////////////////////////////////////// private static RectF screen; private Images imgObj; public Viewer(Context context) { super(context); // TODO Auto-generated constructor stub imgObj = new Images(context); b = new MainActivity().board; Defines.setScreenRender(1280, 800); makeTileImages(Board.MAXGROUPS); } #Override protected void onDraw(Canvas canvas){ drawBackGround(imgObj.bg01, canvas); try{ tTile = b.getContent(); if(tTile==null || tileImages==null){ return; } drawTile(tTile, canvas); }catch (Exception e) { // TODO: handle exception } } #Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub Log.d("Mydebug", "YEHHHHHH"); Tile[][][] content = b.getContent(); for (int i = 0; i < content.length; i++) { for (int y = 0; y < content[i].length; y++) { for (int x = 0; x < content[i][y].length; x++) { processMouseClick(content, i, y , x, event); } } } return true; } public void drawBackGround(Bitmap bitmapBG,Canvas canvas){ screen = new RectF(0.0f, 0.0f, Defines.getScreenWidth(),Defines.getScreenHeight()); canvas.drawBitmap(bitmapBG, null, screen, null); } private void makeTileImages(int groups){ tileImages = loadTileset(groups, "unlit_"); tileImagesHL = loadTileset(groups, "lit_"); } private Bitmap[][] loadTileset(int groups,String prefix){ Bitmap[][] tr = new Bitmap[groups][Board.GROUPSIZE]; try{ InputStream is = this.getResources().getAssets().open("Tiles/tiles.set"); BufferedReader f = new BufferedReader(new InputStreamReader(is)); String s = f.readLine(); while (s!=null) { if (!s.startsWith("#")) { String[] tokens = s.split(" "); try{ int groupNum =Integer.parseInt(tokens[0]); for(int i =1; i<=(Board.GROUPSIZE);i++){ String pathPNG = "Tiles/"+prefix+tokens[i]+".png"; Bitmap img = imgObj.loadImage(pathPNG); img = imgObj.resizeBitmap(img,Tile.tileHeight, Tile.tileWidth); //Bitmap img = loadImage(pathPNG); //Log.d("Mydebug", "PATH:"+pathPNG); tr[groupNum][i-1] = img; } }catch (Exception e) { // TODO: handle exception Log.d("Mydebug", "File error TIles/tile.set"); } } s = f.readLine(); } }catch (Exception e) { // TODO: handle exception } return tr; } public void drawTile(Tile[][][] content,Canvas canvas){ for (int i = 0; i < content.length; i++) { for (int y = 0; y < content[i].length; y++) { for (int x = 0; x < content[i][y].length; x++) { final Tile t = content[i][y][x]; if (t != null) { if (y>0 && content[i][y-1][x]!=null && t.equals(content[i][y-1][x])) { continue; } if (x>0 && content[i][y][x-1]!=null && t.equals(content[i][y][x-1])) { continue; } Bitmap image = tileImages[t.getValue()][t.getSubindex()]; if (b.free(t)) { image = tileImagesHL[t.getValue()][t.getSubindex()]; } /* Draw tile images to panel */ //canvas.drawBitmap(image, x*TILEW+TILEW/2+i*TILESKEW, (y+1)*TILEH/2-i*TILESKEW, null); canvas.drawBitmap(image, (x*TILEW+TILEW/2+i*TILESKEW)+200, ((y+1)*TILEH/2-i*TILESKEW)+100, null); } } } } } /** A helper function for the Viewer constructor which accompanies the mouseListener object on each tiles * #param content The current board's 3D array of positions * #param i The current tile's x position * #param y The current tile's y position * #param x The current tile's z position * #param me The mouseEvent for each tile */ private void processMouseClick(Tile[][][] content, int i, int y, int x, MotionEvent touchPos){ final Tile t = content[i][y][x]; if (t != null) { if (y>0 && content[i][y-1][x]!=null && t.equals(content[i][y-1][x])) { return; } if (x>0 && content[i][y][x-1]!=null && t.equals(content[i][y][x-1])) { return; } Bitmap image = tileImages[t.getValue()][t.getSubindex()]; if (b.free(t)) { image = tileImagesHL[t.getValue()][t.getSubindex()]; } // Rectangle representing space of tile final Rect rect = new Rect(x*TILEW+TILEW/2+i*TILESKEW, (y+1)*TILEH/2-i*TILESKEW, image.getWidth(), image.getHeight()); //if ((rect.contains(me.getPoint())) && b.free(t) && t.isVisible()) { if ((rect.contains((int)touchPos.getX(), (int)touchPos.getY()) && b.free(t))){ t.wasClicked = true; firstIter = false; Log.d("MyDebug", "Clicked ME"); //if (content[i][y][x].isVisible()){ //Add corresponding JLabel to panel // t.tLabel.setBounds(x*TILEW+TILEW/2+i*TILESKEW, (y+1)*TILEH/2-i*TILESKEW, image.getWidth(null), image.getHeight(null)); // t.tLabel.setVisible(false); // t.tLabel.setBorder(BorderFactory.createLineBorder(Color.blue, 2)); //} //validClick(t); } } } }
remove implements OnTouchListener and override the method: public boolean onTouch(MotionEvent event) update of course it's onTouchEvent, not onTouch