2011-08-10 13 views
5

Mam następujące wyjściowe Kody stream:kompresji bitmap Android nie jest dobre

 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(); 

ale wydawało się, powstałego obrazu nie jest to, czego oczekuję. ma pewne linie, jak widać, chcę pozbyć się poziomej białej linii. Co może być przyczyną tego?

enter image description here

dziękuję za wszelką pomoc można dać! :)

UPDATE: Oto klasa CaptureSignature.java gdzie „ja myślę” Mam problem z:

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

Zasadniczo, staram się uchwycić podpis użytkownika i zapisać go na png plik na moim sdcard z urządzenia z Androidem.

Odpowiedz

2

Nigdy nie widziałem takiego problemu z naszą kompresją PNG. Czy to nie może być oryginalna bitmapa?

+0

wielkie dzięki za odpowiedź, co rozumiesz jako oryginalną bitmapę? Zaktualizowałem moje pytanie, może to nam pomoże. – Emkey

+1

Dlaczego używasz nBitmap.setDensity (50)? –

+0

Właśnie próbowałem, jeśli to pomogłoby. Ale nawet jeśli nie ustawiłem gęstości, nadal otrzymuję taki sam wynik. – Emkey

0

Oryginalna mapa bitowa może mieć linie z powodu brudnego lub tłustego ekranu, gdy osoba wykonała podpis. Widziałam też ekran z liniami takimi jak ten, gdy był wadliwy.

0

Metoda onTouch ma w sobie wiele rzeczy (jak przydział pamięci - używanie nowych). To wydaje się być przyczyną twojego problemu. OnTouch jest wywoływany wiele razy na sekundę, gdy użytkownik dotyka ekranu. Jeśli ta metoda nie powróci w czasie, następne wywołanie onTouch nie ma miejsca. Pewnie dlatego masz kilka brakujących "kresek" w wynikowym obrazie. Oczyść kod i zobacz wyniki. Jeśli to nie pomoże, lub nawet inaczej, można użyć mój kod:

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

Stworzyłem własną „Widok” poprzez rozszerzenie klasy View. Właśnie wyodrębniam ścieżkę, gdy użytkownik porusza palcem. Ponieważ używam path.line. Moja ścieżka nigdy nie jest zepsuta. Dostaję cienką linię. Po narysowaniu ścieżki mogę zrobić to, co chcę (używając metody charDrwan()). Tworzę mapę bitową, tworząc Canvas i używając jej metody canvas.drawPath(Path,Paint).