2011-08-10 35 views
5

我得到了下面的輸出流代碼:Android的位圖壓縮不好

 String output_file = APP_FILE_PATH + "/AudienceSignatures/" + CaptureSignature.this.sessionNumber + ".png"; 

     final FileOutputStream out = new FileOutputStream(new File(output_file)); 
     nBitmap.compress(Bitmap.CompressFormat.PNG, 100, out); 
     out.flush(); 
     out.close(); 

,但它似乎像得到的圖像是不是我期待的。它有幾行你可以看到,我想擺脫那些水平的白線。這可能是什麼原因?

enter image description here

非常感謝你可以給任何幫助! :)

更新:這裏是CaptureSignature.java類,其中「我想」我有一個問題:

package com.first.MyApp.drawings; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.app.Dialog; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.Environment; 
import android.os.Handler; 
import android.os.Message; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.View; 
import android.widget.Button; 

import com.first.Engagia.Camera; 
import com.first.Engagia.R; 
import com.first.Engagia.R.id; 
import com.first.Engagia.R.layout; 
import com.first.Engagia.drawings.brush.Brush; 
import com.first.Engagia.drawings.brush.CircleBrush; 
import com.first.Engagia.drawings.brush.PenBrush; 

import java.io.File; 
import java.io.FileOutputStream; 

public class CaptureSignature extends Activity implements View.OnTouchListener{ 
    private DrawingSurface drawingSurface; 
    private DrawingPath currentDrawingPath; 
    private Paint currentPaint; 

    private Brush currentBrush; 

    private File APP_FILE_PATH = new File(Environment.getExternalStorageDirectory() + "/Engagia/AudienceSignatures"); 

    //..some other instance variables here 

    public static final String LOG_TAG = "-------->>>> CAPTURE SIGNATURE <<<<-------"; 
    private ProgressDialog mProgressDialog; 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.drawing_activity); 

     Log.d(LOG_TAG, "Inside capture signature"); 

     PopIt("Camera", "Please sign on the whitespace provided."); 

     Bundle extras = getIntent().getExtras(); 

     if(extras != null){ 
      this.userId = extras.getString("userId"); 
      this.appview_username = extras.getString("username"); 
      this.appview_password = extras.getString("password"); 

      this.userfirstname = extras.getString("userfirstname"); 
      this.userlastname = extras.getString("userlastname"); 
      this.companyname = extras.getString("companyname"); 

      this.sessionNumber = extras.getString("sessionNumber"); 
      this.sessionFirstname = extras.getString("sessionFirstname"); 
      this.sessionLastname = extras.getString("sessionLastname"); 

      this.AudienceFirstnameLastname = extras.getString("AudienceFirstnameLastname"); 

     } 

     setCurrentPaint(); 
     currentBrush = new PenBrush(); 

     drawingSurface = (DrawingSurface) findViewById(R.id.drawingSurface); 
     drawingSurface.setOnTouchListener(this); 
     drawingSurface.previewPath = new DrawingPath(); 
     drawingSurface.previewPath.path = new Path(); 
     drawingSurface.previewPath.paint = getPreviewPaint(); 


    } 

    public void PopIt(String title, String message){ 
     android.content.DialogInterface.OnClickListener arg1 = null; 
     new AlertDialog.Builder(this) 
     .setTitle(title) 
     .setMessage(message) 
     .setPositiveButton("OK", arg1).show(); 
    } 


    private void setCurrentPaint(){ 
     currentPaint = new Paint(); 
     currentPaint.setDither(true); 
     currentPaint.setColor(0xff000000); 
     currentPaint.setStyle(Paint.Style.STROKE); 
     currentPaint.setStrokeJoin(Paint.Join.ROUND); 
     currentPaint.setStrokeCap(Paint.Cap.ROUND); 
     currentPaint.setStrokeWidth(8); 

    } 

    private Paint getPreviewPaint(){ 
     final Paint previewPaint = new Paint(); 
     previewPaint.setColor(0xff000000); 
     previewPaint.setStyle(Paint.Style.STROKE); 
     previewPaint.setStrokeJoin(Paint.Join.ROUND); 
     previewPaint.setStrokeCap(Paint.Cap.ROUND); 
     previewPaint.setStrokeWidth(8); 
     return previewPaint; 
    } 




    public boolean onTouch(View view, MotionEvent motionEvent) { 
     if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){ 
      drawingSurface.isDrawing = true; 

      currentDrawingPath = new DrawingPath(); 
      currentDrawingPath.paint = currentPaint; 
      currentDrawingPath.path = new Path(); 
      currentBrush.mouseDown(currentDrawingPath.path, motionEvent.getX(), motionEvent.getY()); 
      currentBrush.mouseDown(drawingSurface.previewPath.path, motionEvent.getX(), motionEvent.getY()); 


     }else if(motionEvent.getAction() == MotionEvent.ACTION_MOVE){ 
      drawingSurface.isDrawing = true; 
      currentBrush.mouseMove(currentDrawingPath.path, motionEvent.getX(), motionEvent.getY()); 
      currentBrush.mouseMove(drawingSurface.previewPath.path, motionEvent.getX(), motionEvent.getY()); 


     }else if(motionEvent.getAction() == MotionEvent.ACTION_UP){ 


      currentBrush.mouseUp(drawingSurface.previewPath.path, motionEvent.getX(), motionEvent.getY()); 
      drawingSurface.previewPath.path = new Path(); 
      drawingSurface.addDrawingPath(currentDrawingPath); 

      currentBrush.mouseUp(currentDrawingPath.path, motionEvent.getX(), motionEvent.getY()); 

     } 

     return true; 
    } 


    public void onClick(View view){ 
     switch (view.getId()){ 
      case R.id.saveBtn: 
       Log.d(LOG_TAG, "Save Button clicked!"); 


       showDialog(0); 
       CaptureSignature.this.mProgressDialog.setMessage("Saving your signature..."); 

       final Activity currentActivity = this; 
       Handler saveHandler = new Handler(){ 
        @Override 
        public void handleMessage(Message msg) { 
         final AlertDialog alertDialog = new AlertDialog.Builder(currentActivity).create(); 
         alertDialog.setTitle("Done"); 
         alertDialog.setMessage("Your signature has been captured."); 
         alertDialog.setButton("OK", new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int which) { 

           Log.d(LOG_TAG, "Going to camera activity"); 

           //...intent to next activity after signature was taken 

           return; 
          } 
         }); 

         if(CaptureSignature.this.mProgressDialog.isShowing()){ 
          dismissDialog(0); 
         } 

         alertDialog.show(); 
        } 
       } ; 
       new ExportBitmapToFile(this,saveHandler, drawingSurface.getBitmap()).execute(); 
      break; 
      case R.id.resetBtn: 
       Log.d(LOG_TAG, "Reset Button clicked!"); 

       //..reset intent here 

       break; 

     } 
    } 


    private class ExportBitmapToFile extends AsyncTask<Intent,Void,Boolean> { 
     private Context mContext; 
     private Handler mHandler; 
     private Bitmap nBitmap; 

     public ExportBitmapToFile(Context context,Handler handler,Bitmap bitmap) { 
      mContext = context; 
      nBitmap = bitmap; 
      mHandler = handler; 
     } 

     @Override 
     protected Boolean doInBackground(Intent... arg0) { 
      try { 
       if (!APP_FILE_PATH.exists()) { 
        APP_FILE_PATH.mkdirs(); 
       } 
       Log.d(LOG_TAG, "Sig.output stream area."); 

       final FileOutputStream out = new FileOutputStream(new File(APP_FILE_PATH + "/" + CaptureSignature.this.sessionNumber + ".png")); 
       nBitmap.setDensity(50); 
       nBitmap.compress(Bitmap.CompressFormat.PNG, 50, out); 

       out.flush(); 
       out.close(); 

       Log.d(LOG_TAG, "Done bitmap compress."); 
       return true; 
      }catch (Exception e) { 
       e.printStackTrace(); 
      } 

      return false; 
     } 


     @Override 
     protected void onPostExecute(Boolean bool) { 
      super.onPostExecute(bool); 
      if (bool){ 
       mHandler.sendEmptyMessage(1); 
      } 
     } 
    } 

    @Override 
    public void onBackPressed() { 

    } 

    @Override 
    protected Dialog onCreateDialog(int id) { 
     switch (id) { 
      case 0: 
       mProgressDialog = new ProgressDialog(this); 
       mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
       mProgressDialog.show(); 
       return mProgressDialog; 
      default: 
       return null; 
     } 
    } 
} 

基本上,我試圖捕捉用戶的簽名,並將其保存爲PNG文件在我的Android設備SD卡。

回答

2

我從來沒有見過這樣的問題,我們的PNG壓縮。難道它不是原始位圖嗎?

+0

非常感謝您的回覆,您的意思是什麼原始位圖?我更新了我的問題,也許這對我們有幫助。 – Emkey

+1

爲什麼你使用nBitmap.setDensity(50)? –

+0

我只是在嘗試,如果它會幫助。但即使我沒有設定密度,我仍然得到相同的結果。 – Emkey

0

原始位圖可能會有人在簽名時由於髒或油性屏幕而產生的行。當它發生故障時,我也看到了一個這樣的線條。

0

onTouch方法中有很多事情正在進行(如內存分配 - 使用新的)。這似乎是你的問題的根源。當用戶觸摸屏幕時,onTouch每秒被調用多次。如果此方法未及時返回,則不會發生下一次onTouch調用。這可能就是爲什麼你在結果圖像中缺少一些「筆觸」。清理代碼並查看結果。如果沒有幫助,甚至否則,你可以使用我的代碼:

public boolean onTouchEvent(MotionEvent event){ 
    final int source = event.getSource(); 
    if(source!=InputDevice.SOURCE_TOUCHSCREEN && 
      source!=InputDevice.SOURCE_MOUSE && 
      source!=InputDevice.SOURCE_TOUCHPAD){ 
     Log.v(TAG, "returns false"); 

     return false; 
    } 

    switch(event.getActionMasked()){ 
    case MotionEvent.ACTION_DOWN: 
     path.reset(); 
     path.moveTo(event.getX(), event.getY()); 
     break; 
    case MotionEvent.ACTION_MOVE: 
     path.lineTo(event.getX(), event.getY()); 
     break; 
    case MotionEvent.ACTION_UP: 
     path.lineTo(event.getX(), event.getY()); 
     charDrawn(); 
    } 
    invalidate();//omit this. I need it since it calls the onDraw() method 
    Log.v(TAG, "returns true"); 
    return true; 
} 

我已經通過擴展View類創建了自己的「查看」。我只是在用戶移動手指時提取路徑。由於我使用path.lineTo我的路徑永遠不會中斷。我得到一條細線。一旦路徑被繪製出來,我可以做任何我想要的東西(在charDrwan()方法中)。我通過創建一個Canvas並使用其canvas.drawPath(Path,Paint)方法創建一個位圖。