Android Canvas - Save Image not working
I have used below example code to place image files onto a canvas in Android and I'm struggling getting it to save the entire image to SDCard. At the moment it only saves a strange close up of one of the images. Any idea on what is going wrong?
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;
public class ebpSeatingPlan extends Activity {
public Panel myPanel;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//requestWindowFeature(Window.FEATURE_NO_TITLE);
myPanel = new Panel(this);
setContentView(myPanel);
myPanel.setImageID(R.drawable.tableperson);
}
private static final int TYPE1 = 0;
private static final int TYPE2 = 1;
private static final int TYPE3 = 2;
private static final int EXIT = 3;
private static final int TYPE4 = 4;
public boolean onCreateOptionsMenu(Menu menu){
menu.add(0,TYPE1,0,"Guest Type 1").setIcon(R.drawable.tableperson);
menu.add(0,TYPE2,0,"Guest Type 2").setIcon(R.drawable.tableperson2);
menu.add(0,TYPE3,0,"Guest Type 3").setIcon(R.drawable.tableperson3);
menu.add(0,TYPE4,0,"Save Image").setIcon(R.drawable.frame);
menu.add(0,EXIT,0,"Back to Main Menu").setIcon(R.drawable.exit);
return true;
}
public boolean onOptionsItemSelected (MenuItem item){
switch (item.getItemId()){
case TYPE1:
myPanel.setImageID(R.drawable.tableperson);
return true;
case TYPE2:
myPanel.setImageID(R.drawable.tableperson2);
return true;
case TYPE3:
myPanel.setImageID( R.drawable.tableperson3);
return true;
case TYPE4:
File myDir = new File("/sdcard/saved_images");
myDir.mkdirs();
Date now = new Date();
String fname = "image"+now.getDate()+now.getSeconds()+".jpg";
File file = new File(myDir, fname);
myPanel.saveAsJpg(file, myPanel);
return true;
case EXIT:
finish();
return true;
}
return false;
}
}
class Panel extends SurfaceView implements SurfaceHolder.Callback {
public int chosenImageId;
//public Bitmap bitmap;
private TutorialThread _thread;
private ArrayList<GraphicObject> _graphics = new ArrayList<GraphicObject>();
private GraphicObject _currentGraphic = null;
public void setImageID(int i){
chosenImageId = i;
}
public void saveAsJpg(File f, View v){
String fname = f.getAbsolutePath();
FileOutputStream fos = null;
try{
fos = new FileOutputStream(fname);
Bitmap b = Bitmap.createBitmap(v.getWidth(),v.getHeight(),Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
//bitmap.compress(CompressFormat.JPEG, 100, fos);
b.compress(CompressFormat.JPEG, 100, fos);
Toast.makeText(super.getContext(),"Image Saved", Toast.LENGTH_LONG).show();
}catch (Exception ex){
Toast.makeText(super.getContext(),"Error Saving Image", Toast.LENGTH_LONG).show();
Log.i("DAVE","stacktrace is " + ex);
}
}
public Panel(Context context) {
super(context);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
setFocusable(true);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (_thread.getSurfaceHolder()) {
GraphicObject graphic = null;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
graphic = new GraphicObject(BitmapFactory.decodeResource(getResources(), chosenImageId));
graphic.getCoordinates().setX((int) event.getX() - graphic.getGraphic().getWidth() / 2);
graphic.getCoordinates().setY((int) event.getY() - graphic.getGraphic().getHeight() / 2);
_currentGraphic = graphic;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
_currentGraphic.getCoordinates().setX((int) event.getX() - _currentGraphic.getGraphic().getWidth() / 2);
_currentGraphic.getCoordinates().setY((int) event.getY() - _currentGraphic.getGraphic().getHeight() / 2);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
_graphics.add(_currentGraphic);
_currentGraphic = null;
}
return true;
}
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.LTGRAY);
Bitmap bitmap=null;
GraphicObject.Coordinates coords;
for (GraphicObject graphic : _graphics) {
bitmap = graphic.getGraphic();
coords = graphic.getCoordinates();
canvas.drawBitmap(bitmap, coords.getX(), coords.getY(), null);
}
if (_currentGraphic != null) {
bitmap = _currentGraphic.getGraphic();
coords = _currentGraphic.getCoordinates();
canvas.drawBitmap(bitmap, coords.getX(), coords.getY(), null);
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
_thread.setRunning(true);
_thread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}
class TutorialThread extends Thread {
private SurfaceHolder _surfaceHolder;
private Panel _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
开发者_StackOverflow }
public void setRunning(boolean run) {
_run = run;
}
public SurfaceHolder getSurfaceHolder() {
return _surfaceHolder;
}
@Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
class GraphicObject {
public class Speed {
public static final int X_DIRECTION_RIGHT = 1;
public static final int X_DIRECTION_LEFT = -1;
public static final int Y_DIRECTION_DOWN = 1;
public static final int Y_DIRECTION_UP = -1;
private int _x = 1;
private int _y = 1;
private int _xDirection = X_DIRECTION_RIGHT;
private int _yDirection = Y_DIRECTION_DOWN;
public int getXDirection() {
return _xDirection;
}
public void setXDirection(int direction) {
_xDirection = direction;
}
public void toggleXDirection() {
if (_xDirection == X_DIRECTION_RIGHT) {
_xDirection = X_DIRECTION_LEFT;
} else {
_xDirection = X_DIRECTION_RIGHT;
}
}
public int getYDirection() {
return _yDirection;
}
public void setYDirection(int direction) {
_yDirection = direction;
}
public void toggleYDirection() {
if (_yDirection == Y_DIRECTION_DOWN) {
_yDirection = Y_DIRECTION_UP;
} else {
_yDirection = Y_DIRECTION_DOWN;
}
}
public int getX() {
return _x;
}
public void setX(int speed) {
_x = speed;
}
public int getY() {
return _y;
}
public void setY(int speed) {
_y = speed;
}
public String toString() {
String xDirection;
String yDirection;
if (_xDirection == X_DIRECTION_RIGHT) {
xDirection = "right";
} else {
xDirection = "left";
}
if (_yDirection == Y_DIRECTION_UP) {
yDirection = "up";
} else {
yDirection = "down";
}
return "Speed: x: " + _x + " | y: " + _y + " | xDirection: " + xDirection + " | yDirection: " + yDirection;
}
}
public class Coordinates {
private int _x = 100;
private int _y = 0;
public int getX() {
return _x + _bitmap.getWidth() / 2;
}
public void setX(int value) {
_x = value - _bitmap.getWidth() / 2;
}
public int getY() {
return _y + _bitmap.getHeight() / 2;
}
public void setY(int value) {
_y = value - _bitmap.getHeight() / 2;
}
public String toString() {
return "Coordinates: (" + _x + "/" + _y + ")";
}
}
private Bitmap _bitmap;
private Coordinates _coordinates;
public GraphicObject(Bitmap bitmap) {
_bitmap = bitmap;
_coordinates = new Coordinates();
}
public Bitmap getGraphic() {
return _bitmap;
}
public Coordinates getCoordinates() {
return _coordinates;
}
}
you can use drawing cache of view to save image
first enable drawingcache of you view by
myPanel.setDrawingCacheEnabled(true);
after that in your saveImage function write following code
Bitmap bitMap=v.getDrawingCache(true);
if (!APP_FILE_PATH.exists()) {
APP_FILE_PATH.mkdirs();
}
bitMap.compress(Bitmap.CompressFormat.PNG, 95, f);
精彩评论