2011-08-10 16 views
5

Tengo las siguientes códigos flujo de salida:compresión de mapa de bits Android no es bueno

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

pero parecía que la imagen resultante no es lo que estoy esperando. tiene algún tipo de líneas como puede ver, quiero deshacerme de esas líneas blancas horizontales. ¿Cuál podría ser la causa de esto? una gran cantidad de cualquier ayuda que pueda dar

enter image description here

Gracias! :)

ACTUALIZACIÓN: Aquí está la clase CaptureSignature.java donde 'pienso' Estoy teniendo un problema con:

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

Básicamente, estoy tratando de capturar la firma del usuario y guardarlo en png archivo en mi tarjeta SD de dispositivo Android.

Respuesta

2

Nunca he visto un problema con nuestra compresión PNG. ¿No podría ser el mapa de bits original?

+0

muchas gracias por su respuesta, ¿qué quiere decir con el mapa de bits original? Actualicé mi pregunta, tal vez eso nos ayudaría. – Emkey

+1

¿Por qué usas nBitmap.setDensity (50)? –

+0

Estaba intentando realmente si fuera de ayuda. Pero incluso si no configuré la densidad, sigo obteniendo el mismo resultado. – Emkey

0

El mapa de bits original puede tener líneas debido a una pantalla sucia o grasienta cuando la persona hizo la firma. También vi una pantalla con líneas como esta cuando estaba defectuoso.

0

El método onTouch tiene muchas cosas sucediendo dentro de él (como las asignaciones de memoria, usando nuevas). Esta parece ser la causa raíz de tu problema. El dispositivo onTouch se invoca muchas veces por segundo cuando un usuario toca la pantalla. Si este método no regresa a tiempo, la próxima llamada a onTouch no se realizará. Esa es probablemente la razón por la que tiene algunos "trazos" faltantes en la imagen resultante. Limpie el código y vea los resultados. Si eso no ayuda, o incluso de otro modo, puede utilizar mi código:

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

He creado mi propio "Vista" extendiendo la clase View. Solo extraigo la ruta mientras el usuario mueve su dedo. Como utilizo path.lineTo mi ruta nunca se rompe. Tengo una línea delgada. Una vez que se dibuja la ruta, puedo hacer lo que quiera con ella (en el método charDrwan()). Creo un mapa de bits creando un Canvas y usando su método canvas.drawPath(Path,Paint).

Cuestiones relacionadas