Android Open Source - AsciiCamera Ascii Cam Activity






From Project

Back to project page AsciiCamera.

License

The source code is released under:

Apache License

If you think the Android project AsciiCamera listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

// Copyright (C) 2014 Bruno Ramalhete
//from   w ww.  j  a v  a 2  s.  c o  m
package com.spectralsoftware.asciicamera;

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.EnumMap;
import java.util.Map;

import com.spectralsoftware.asciicamera.R;
import com.spectralsoftware.util.ARManager;
import com.spectralsoftware.util.AndroidUtils;
import com.spectralsoftware.util.CameraPreviewProcessingQueue;
import com.spectralsoftware.util.CameraUtils;
import com.spectralsoftware.util.ShutterButton;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.Toast;

public class AsciiCamActivity extends Activity 
        implements Camera.PreviewCallback, ShutterButton.OnShutterButtonListener, CameraPreviewProcessingQueue.Processor {
    
    ARManager arManager;
    AsciiConverter asciiConverter = new AsciiConverter();
    AsciiConverter.Result asciiResult = new AsciiConverter.Result();
    
    AsciiConverter.ColorType colorType = AsciiConverter.ColorType.ANSI_COLOR;
    Map<AsciiConverter.ColorType, String> pixelCharsMap = new EnumMap<AsciiConverter.ColorType, String>(AsciiConverter.ColorType.class);
    
    Object pictureLock = new Object();
    final static int ACTIVITY_PREFERENCES = 1;
    final static int ACTIVITY_PICK_IMAGE = 2;
    
    ImageButton cycleColorButton;
    ShutterButton shutterButton;
    SurfaceView cameraView;
    OverlayView overlayView;

    Handler handler = new Handler();
    boolean saveInProgress = false;
    boolean cameraViewReady = false;
    boolean appVisible = false;
    
    AsciiRenderer imageRenderer = new AsciiRenderer();
    AsciiImageWriter imageWriter = new AsciiImageWriter();
    
    CameraPreviewProcessingQueue imageProcessor = new CameraPreviewProcessingQueue();

    /** Called when the activity is first created. */
    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
        
        cameraView = (SurfaceView)findViewById(R.id.cameraView);
        overlayView = (OverlayView)findViewById(R.id.overlayView);
        cycleColorButton = (ImageButton)findViewById(R.id.cycleColorButton);
        shutterButton = (ShutterButton)findViewById(R.id.shutterButton);
        shutterButton.setOnShutterButtonListener(this);
        
        arManager = ARManager.createAndSetupCameraView(this, cameraView, this);
        arManager.setPreferredPreviewSize(640,400);
        arManager.setNumberOfPreviewCallbackBuffers(1);

        findViewById(R.id.switchCameraButton).setVisibility(CameraUtils.numberOfCameras() > 1 ? View.VISIBLE : View.GONE);
        updateFromPreferences();
        updateColorButton();
    }
    
    @Override public void onPause() {
        appVisible = false;
        arManager.stopCamera();
        asciiConverter.destroyThreadPool();
        imageProcessor.stop();
        super.onPause();
    }
    
    @Override public void onResume() {
        super.onResume();
        appVisible = true;
        arManager.startCameraIfVisible();
        imageProcessor.start(this);
        AndroidUtils.setSystemUiLowProfile(cameraView);
    }

    void updateFromPreferences() {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        for(AsciiConverter.ColorType colorType : AsciiConverter.ColorType.values()) {
          String prefsKey = getString(R.string.pixelCharsPrefIdPrefix) + colorType.name();
          pixelCharsMap.put(colorType, prefs.getString(prefsKey, ""));
        }
        
        String colorTypeName = prefs.getString("colorType", null);
        if (colorTypeName!=null) {
          try {
            this.colorType = AsciiConverter.ColorType.valueOf(colorTypeName);;
          }
          catch(Exception ignored) {}
        }
        if (colorType==null) {
          colorType = AsciiConverter.ColorType.ANSI_COLOR;
        }
        AsciiCamPreferences.setAutoConvertEnabled(this, prefs.getBoolean(getString(R.string.autoConvertPicturesPrefId), false));
    }
    
    void saveColorStyleToPreferences() {
      SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).edit();
      editor.putString("colorType", colorType.name());
      editor.commit();
    }
    
    @Override protected void onActivityResult(int requestCode, int resultCode, final Intent intent) { 
        super.onActivityResult(requestCode, resultCode, intent); 

        switch(requestCode) { 
            case ACTIVITY_PREFERENCES:
                updateFromPreferences();
                break;
            case ACTIVITY_PICK_IMAGE:
                if (resultCode==RESULT_OK) {
                    (new Thread() {
                        public void run() {
                            try {
                                final String imagePath = (new ProcessImageOperation()).
                                        processImage(AsciiCamActivity.this, intent.getData());
                                handler.post(new Runnable() {
                                    public void run() {
                                        ViewImageActivity.startActivityWithImageURI(AsciiCamActivity.this, 
                                                Uri.fromFile(new File(imagePath)), "image/png");
                                    }
                                });
                            }
                            catch(Exception ex) {
                                Log.e("ConvertImage", "Failed converting image", ex);
                            }
                        }
                    }).start();
                }
                break;
        }
    }
    
    void takePictureThreadEntry(final AsciiConverter.Result result) {
        try {
            final String pngPath = imageWriter.saveImageAndThumbnail(imageRenderer.getVisibleBitmap(), 
                    imageRenderer.createThumbnailBitmap(result),
                    new AsciiImageWriter.HtmlProvider() {
                        public void writeHtml(Writer writer, String imageName) throws IOException {
                            imageRenderer.writeHtml(result, writer, imageName);
                        }
                    }
            );
            handler.post(new Runnable() {
               public void run() {
                   bitmapSaved(pngPath, "image/png");
               }
            });
        }
        catch(IOException ex) {
            Log.e("AsciiCam", "Error saving picture", ex);
        }
    }
    
    void takePicture() {
        if (saveInProgress) return;
        // use a separate thread to write the PNG and HTML files, so the UI doesn't block
        imageProcessor.pause();
        (new Thread() {
            public void run() {
                AsciiConverter.Result savePictureResult = null;
                synchronized(pictureLock) {
                    savePictureResult = asciiResult.copy();
                }
                try {
                    takePictureThreadEntry(savePictureResult);                    
                }
                finally {
                    imageProcessor.unpause();
                }
            }
        }).start();
    }
    
    void bitmapSaved(String path, String mimeType) {
        saveInProgress = false;
        if (!appVisible) return;
        if (path==null) {
            Toast.makeText(getApplicationContext(), getString(R.string.errorSavingPicture), Toast.LENGTH_SHORT).show();
        }
        else {
            ViewImageActivity.startActivityWithImageURI(this, Uri.fromFile(new File(path)), mimeType);
        }
    }

    void updateColorButton() {
      try {
        String resName = "btn_color_" + this.colorType.name().toLowerCase();
        Integer resId = (Integer)R.drawable.class.getField(resName).get(null);
        cycleColorButton.setImageResource(resId);
      }
      catch(Exception ex) {
        Log.e("AsciiCam", "Error updating color button", ex);
      }
    }
    
    // onClick_ methods are assigned as onclick handlers in the main.xml layout
    public void onClick_cycleColorMode(View view) {
      AsciiConverter.ColorType[] colorTypeValues = AsciiConverter.ColorType.values();
      this.colorType = colorTypeValues[(this.colorType.ordinal() + 1) % colorTypeValues.length];
        saveColorStyleToPreferences();
        updateColorButton();
    }
    
    public void onClick_gotoGallery(View view) {
        Intent intent = LibraryActivity.intentWithImageDirectory(this,
                imageWriter.getBasePictureDirectory(), imageWriter.getThumbnailDirectory());
        startActivity(intent);
    }
    
    public void onClick_gotoAbout(View view) {
        AboutActivity.startIntent(this);
    }
    
    public void onClick_gotoPreferences(View view) {
        AsciiCamPreferences.startIntent(this, ACTIVITY_PREFERENCES);
    }
    
    public void onClick_switchCamera(View view) {
        arManager.switchToNextCamera();
    }
    
    public void onClick_convertPicture(View view) {
        Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI); 
        startActivityForResult(i, ACTIVITY_PICK_IMAGE);         
    }
    
    @Override public void onPreviewFrame(byte[] data, Camera camera) {
        if (!saveInProgress) {
            Camera.Size size = camera.getParameters().getPreviewSize();
            imageProcessor.processImageData(data, size.width, size.height);
        }
        else {
            CameraUtils.addPreviewCallbackBuffer(camera, data);
        }
    }
    
    @Override public void processCameraImage(final byte[] data, final int width, final int height) {
        synchronized(pictureLock) {
            imageRenderer.setMaximumImageSize(overlayView.getWidth(), overlayView.getHeight());
            imageRenderer.setCameraImageSize(width, height);
            asciiConverter.computeResultForCameraData(data, width, height, 
                    imageRenderer.asciiRows(), imageRenderer.asciiColumns(), 
                    colorType, pixelCharsMap.get(colorType), asciiResult);
            overlayView.setBitmap(imageRenderer.createBitmap(asciiResult));
            // When using a front-facing camera, the displayed image needs to be mirrored;
            // otherwise it will appear upside down in portrait orientation.
            overlayView.setFlipHorizontal(arManager.isCameraFrontFacing());
        }
        handler.post(new Runnable() {
           public void run() {
               CameraUtils.addPreviewCallbackBuffer(arManager.getCamera(), data);
               overlayView.invalidate();
           }
        });
    }
    
  @Override public void onShutterButtonFocus(boolean pressed) {
    shutterButton.setImageResource(pressed ? R.drawable.btn_camera_shutter_pressed_holo : 
                                           R.drawable.btn_camera_shutter_holo);
  }

  @Override public void onShutterButtonClick() {
    takePicture();
  }

  @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
      // take picture when pushing hardware camera button or trackball center
      if ((keyCode==KeyEvent.KEYCODE_CAMERA || keyCode==KeyEvent.KEYCODE_DPAD_CENTER) && event.getRepeatCount()==0) {
          handler.post(new Runnable() {
              public void run() {
                  takePicture();
              }
          });
          return true;
      }
      return super.onKeyDown(keyCode, event);
  }

}




Java Source Code List

com.spectralsoftware.asciicamera.AboutActivity.java
com.spectralsoftware.asciicamera.AsciiCamActivity.java
com.spectralsoftware.asciicamera.AsciiCamPreferences.java
com.spectralsoftware.asciicamera.AsciiConverter.java
com.spectralsoftware.asciicamera.AsciiImageWriter.java
com.spectralsoftware.asciicamera.AsciiRenderer.java
com.spectralsoftware.asciicamera.ImageDirectory.java
com.spectralsoftware.asciicamera.LibraryActivity.java
com.spectralsoftware.asciicamera.NewPictureReceiverLegacyBroadcast.java
com.spectralsoftware.asciicamera.NewPictureReceiver.java
com.spectralsoftware.asciicamera.OverlayView.java
com.spectralsoftware.asciicamera.ProcessImageOperation.java
com.spectralsoftware.asciicamera.ViewImageActivity.java
com.spectralsoftware.util.ARManager.java
com.spectralsoftware.util.AndroidUtils.java
com.spectralsoftware.util.AsyncImageLoader.java
com.spectralsoftware.util.CameraPreviewProcessingQueue.java
com.spectralsoftware.util.CameraUtils.java
com.spectralsoftware.util.ScaledBitmapCache.java
com.spectralsoftware.util.ShutterButton.java
com.spectralsoftware.util.SingleItemProcessingQueue.java