2011-03-31 2 views
1

아래 예제 코드를 사용하여 이미지 파일을 Android의 캔버스에 배치하고 전체 이미지를 SDCard에 저장하는 데 어려움을 겪고 있습니다. 현재는 이미지 중 하나의 이상한 클로즈업 만 저장합니다. 무엇이 잘못 될지에 대한 아이디어가 있습니까?Android Canvas - 이미지 저장 안 함

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

} 

답변

0

당신은 첫 번째 코드

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


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

다음 당신의 drawingcache이 saveImage 기능을 쓰기에 그 후

myPanel.setDrawingCacheEnabled(true); 

으로 볼 수 있도록 이미지를

을 저장하는보기의 도면 캐시를 사용할 수 있습니다 안녕 Sunil, 고마워, 슬프게도 마지막 라인에서 NullPointerException을 받고 있어요. 캐시가 비어 있음을 의미합니까? – Atkobeau

+0

당신은 당신에게 로그 캣 예외 세부 사항을 붙여 넣을 수 있습니다 –

+0

java.lang.NullPointerException이 com.ebp.Panel.saveAsJpg (ebpSeatingPlan.java:121) com.ebp.ebpSeatingPlan.onOptionsItemSelected (ebpSeatingPlan.java:80) android.app.Activity에서 .onMenuItemSelected (Activity.java:2200) com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected (PhoneWindow.java:730) com.android.internal.view.menu.MenuItemImpl.invoke (MenuItemImpl.java:139)) com.android.internal.view.menu.MenuBuilder.performItemAction (MenuBuilder.java:855) com.android.internal.view.menu.IconMenuView.invokeItem (IconMenuView.java:525) – Atkobeau