Android Canvas - 保存图片不起作用

时间:2011-03-31 12:58:41

标签: android image canvas bitmap fileoutputstream

我使用下面的示例代码将图像文件放到Android的画布上,我很难将它保存到SDCard中。目前它只能保存其中一个图像的奇怪特写。什么出错了?

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;
        }
        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;
        }

}

1 个答案:

答案 0 :(得分:0)

您可以使用视图的绘图缓存来保存图像

首先启用您通过

查看的drawingcache
myPanel.setDrawingCacheEnabled(true);

之后在saveImage函数中编写以下代码

        Bitmap bitMap=v.getDrawingCache(true);
        if (!APP_FILE_PATH.exists()) {
            APP_FILE_PATH.mkdirs();
        }


         bitMap.compress(Bitmap.CompressFormat.PNG, 95, f);