Android Open Source - Aviary-Android-SDK Tilt Shift Panel






From Project

Back to project page Aviary-Android-SDK.

License

The source code is released under:

AVIARY API TERMS OF USE Full Legal Agreement The following terms and conditions and the terms and conditions at http://www.aviary.com/terms (collectively, the ?Terms??) govern your use of any and ...

If you think the Android project Aviary-Android-SDK 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

package com.aviary.android.feather.effects;
//  ww  w  . j av  a2 s . co  m
import it.sephiroth.android.library.imagezoom.ImageViewTouchBase;
import it.sephiroth.android.library.imagezoom.ImageViewTouchBase.DisplayType;
import it.sephiroth.android.library.imagezoom.ImageViewTouchBase.OnDrawableChangeListener;

import java.util.Iterator;
import java.util.Locale;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.aviary.android.feather.R;
import com.aviary.android.feather.common.utils.os.AviaryAsyncTask;
import com.aviary.android.feather.headless.filters.NativeToolFilter.TiltShiftMode;
import com.aviary.android.feather.headless.moa.MoaActionFactory;
import com.aviary.android.feather.headless.moa.MoaActionList;
import com.aviary.android.feather.library.content.ToolEntry;
import com.aviary.android.feather.library.filters.FilterLoaderFactory;
import com.aviary.android.feather.library.filters.FilterLoaderFactory.Filters;
import com.aviary.android.feather.library.filters.TiltShiftFilter;
import com.aviary.android.feather.library.services.IAviaryController;
import com.aviary.android.feather.library.tracking.Tracker;
import com.aviary.android.feather.library.utils.BitmapUtils;
import com.aviary.android.feather.library.utils.UIConfiguration;
import com.aviary.android.feather.widget.AviaryHighlightImageButton;
import com.aviary.android.feather.widget.AviaryHighlightImageButton.OnCheckedChangeListener;
import com.aviary.android.feather.widget.ImageViewTiltiShiftTouch;
import com.aviary.android.feather.widget.ImageViewTiltiShiftTouch.OnTiltShiftDrawListener;
import com.aviary.android.feather.widget.ImageViewTiltiShiftTouch.TiltShiftDrawMode;

/**
 * The Class SpotDrawPanel.
 */
public class TiltShiftPanel extends AbstractContentPanel implements OnTiltShiftDrawListener, OnDrawableChangeListener, OnCheckedChangeListener {

  private BackgroundDrawThread mBackgroundDrawThread;
  private TiltShiftFilter mFilter;
  private AviaryHighlightImageButton mCircleButton;
  private AviaryHighlightImageButton mRectButton;

  static float BRUSH_MULTIPLIER = 2f;

  MoaActionList mActions = MoaActionFactory.actionList();
  TiltShiftMode mTiltShiftMode;

  public TiltShiftPanel ( IAviaryController context, ToolEntry entry ) {
    super( context, entry );
  }

  @Override
  public void onCreate( Bitmap bitmap, Bundle options ) {
    super.onCreate( bitmap, options );

    mRectButton = (AviaryHighlightImageButton) getOptionView().findViewById( R.id.aviary_button_rectangle );
    mCircleButton = (AviaryHighlightImageButton) getOptionView().findViewById( R.id.aviary_button_circle );
    mImageView = (ImageViewTiltiShiftTouch) getContentView().findViewById( R.id.aviary_image );

    mPreview = Bitmap.createBitmap( mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888 );
    mPreview.eraseColor( Color.BLACK );

    final ImageViewTiltiShiftTouch image = (ImageViewTiltiShiftTouch) mImageView;
    image.setOnDrawableChangedListener( this );
    image.setDisplayType( DisplayType.FIT_IF_BIGGER );
    // image.setPointWaveEnabled( true );

    mCircleButton.setOnCheckedChangeListener( this );
    mRectButton.setOnCheckedChangeListener( this );

    // create the background thread for drawing chanched
    mBackgroundDrawThread = new BackgroundDrawThread( "filter-thread", Thread.NORM_PRIORITY );

    // initialize the filter
    mFilter = createFilter();
  }

  @Override
  public void onActivate() {
    super.onActivate();

    mPreview = BitmapUtils.copy( mBitmap, Config.ARGB_8888 );
    mBackgroundDrawThread.start();

    ( (ImageViewTiltiShiftTouch) mImageView ).setOnDrawStartListener( this );
    mImageView.setDisplayType( DisplayType.FIT_IF_BIGGER );
    mImageView.setImageBitmap( mPreview, null, ImageViewTouchBase.ZOOM_INVALID, UIConfiguration.IMAGE_VIEW_MAX_ZOOM );
    contentReady();
  }

  @Override
  protected void onDispose() {
    mContentReadyListener = null;

    // dispose the filter
    mFilter.dispose();
    super.onDispose();
  }

  @Override
  public void onCheckedChanged( AviaryHighlightImageButton button, boolean isChecked, boolean fromUser ) {

    mLogger.info( "onCheckedChanged: " + isChecked + ", fromUser: " + fromUser );

    final int id = button.getId();

    // button already checked, skip
    if ( !isChecked ) {
      return;
    }

    if ( id == mRectButton.getId() ) {
      mLogger.log( "rect" );
      mTiltShiftMode = TiltShiftMode.Linear;
      mCircleButton.setChecked( false );
    } else if ( id == mCircleButton.getId() ) {
      mLogger.log( "circle" );
      mTiltShiftMode = TiltShiftMode.Radial;
      mRectButton.setChecked( false );
    }

    if ( !fromUser ) {
      mLogger.log( "return" );
      return;
    }

    if ( mTiltShiftMode == TiltShiftMode.Radial ) {
      ( (ImageViewTiltiShiftTouch) mImageView ).setTiltShiftDrawMode( TiltShiftDrawMode.Radial );
      Tracker.recordTag( Filters.TILT_SHIFT.name().toLowerCase( Locale.US ) + ": CircleClicked" );
    } else if ( mTiltShiftMode == TiltShiftMode.Linear ) {
      ( (ImageViewTiltiShiftTouch) mImageView ).setTiltShiftDrawMode( TiltShiftDrawMode.Linear );
      Tracker.recordTag( Filters.TILT_SHIFT.name().toLowerCase( Locale.US ) + ": RectangleClicked" );
    }
  }

  @Override
  public void onDeactivate() {

    mImageView.setOnDrawableChangedListener( null );
    mCircleButton.setOnCheckedChangeListener( this );
    mRectButton.setOnCheckedChangeListener( this );

    ( (ImageViewTiltiShiftTouch) mImageView ).setOnDrawStartListener( null );

    if ( mBackgroundDrawThread != null ) {

      mBackgroundDrawThread.clear();

      if ( mBackgroundDrawThread.isAlive() ) {
        mBackgroundDrawThread.quit();
        while ( mBackgroundDrawThread.isAlive() ) {
          mLogger.log( "isAlive..." );
          // wait...
        }
      }
    }
    onProgressEnd();
    super.onDeactivate();
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    mBackgroundDrawThread = null;
    mImageView.clear();
  }

  @Override
  public void onCancelled() {
    super.onCancelled();
  }

  @Override
  public void onDrawStart( float[] points, TiltShiftDrawMode mode, float radius, float angle, float left, float top, float right, float bottom ) {
    mBackgroundDrawThread.drawStart( points, mode, radius, angle, left, top, right, bottom );
    setIsChanged( true );
  }

  @Override
  public void onDrawing( float[] points, float radius, float angle, float left, float top, float right, float bottom ) {
    mBackgroundDrawThread.draw( points, radius, angle, left, top, right, bottom );
  }

  @Override
  public void onDrawEnd() {
    mBackgroundDrawThread.pathEnd();
  }

  @Override
  public void onDrawableChanged( Drawable drawable ) {

    mLogger.info( "onDrawableChanged: " + drawable );

    if ( mCircleButton.isChecked() ) {
      mTiltShiftMode = TiltShiftMode.Radial;
    } else if ( mRectButton.isChecked() ) {
      mTiltShiftMode = TiltShiftMode.Linear;
    }

    getHandler().postDelayed( new Runnable() {

      @Override
      public void run() {
        ImageViewTiltiShiftTouch image = (ImageViewTiltiShiftTouch) mImageView;

        if ( mTiltShiftMode == TiltShiftMode.Radial ) {
          mCircleButton.setChecked( true );
          image.setTiltShiftDrawMode( TiltShiftDrawMode.Radial );
        } else {
          mRectButton.setChecked( true );
          image.setTiltShiftDrawMode( TiltShiftDrawMode.Linear );
        }
      }
    }, 500 );
  }

  @Override
  protected void onGenerateResult() {
    if ( mBackgroundDrawThread.isAlive() && !mBackgroundDrawThread.isCompleted() ) {
      mBackgroundDrawThread.finish();
      GenerateResultTask task = new GenerateResultTask();
      task.execute();
    } else {
      onComplete( mPreview, mFilter.getActions() );
    }
  }

  @Override
  protected void onComplete( Bitmap bitmap, MoaActionList actions ) {

    if ( mTiltShiftMode == TiltShiftMode.Radial ) mTrackingAttributes.put( "shape", "Circle" );
    else mTrackingAttributes.put( "shape", "Rectangle" );

    super.onComplete( bitmap, actions );
  }

  @SuppressWarnings ( "unused" )
  private String printRect( Rect rect ) {
    return "( left=" + rect.left + ", top=" + rect.top + ", width=" + rect.width() + ", height=" + rect.height() + ")";
  }

  protected TiltShiftFilter createFilter() {
    return (TiltShiftFilter) FilterLoaderFactory.get( Filters.TILT_SHIFT );
  }

  @Override
  protected View generateContentView( LayoutInflater inflater ) {
    return inflater.inflate( R.layout.aviary_content_focus, null );
  }

  @Override
  protected ViewGroup generateOptionView( LayoutInflater inflater, ViewGroup parent ) {
    return (ViewGroup) inflater.inflate( R.layout.aviary_panel_focus, parent, false );
  }

  static class DrawQueue extends LinkedBlockingQueue<float[]> {

    private static final long serialVersionUID = 1L;

    private TiltShiftMode mode_;
    private volatile boolean completed_;

    public DrawQueue ( TiltShiftMode tiltShiftMode ) {
      mode_ = tiltShiftMode;
      completed_ = false;
    }

    public TiltShiftMode getMode() {
      return mode_;
    }

    public void end() {
      completed_ = true;
    }

    public boolean isCompleted() {
      return completed_;
    }
  }

  /**
   * background thread
   */
  class BackgroundDrawThread extends Thread {

    boolean started;
    volatile boolean running;
    final Queue<DrawQueue> mQueue;
    DrawQueue mCurrentQueue;

    public BackgroundDrawThread ( String name, int priority ) {
      super( name );
      mQueue = new LinkedBlockingQueue<DrawQueue>();
      setPriority( priority );
      init();
    }

    void init() {}

    @Override
    synchronized public void start() {
      started = true;
      running = true;
      super.start();
    }

    synchronized public void quit() {
      started = true;
      running = false;
      interrupt();
    };

    synchronized public void drawStart( float points[], TiltShiftDrawMode type, float radius, float angle, float left, float top, float right, float bottom ) {
      if ( !running ) return;

      if ( mCurrentQueue != null ) {
        mCurrentQueue.end();
        mCurrentQueue = null;
      }

      DrawQueue queue = new DrawQueue( type == TiltShiftDrawMode.Radial ? TiltShiftMode.Radial : TiltShiftMode.Linear );
      queue.add( new float[] { points[0], points[1], radius, angle, left, top, right, bottom } );

      mQueue.add( queue );
      mCurrentQueue = queue;
    }

    synchronized public void draw( float points[], float radius, float angle, float left, float top, float right, float bottom ) {
      if ( !running || mCurrentQueue == null ) return;

      mCurrentQueue.clear();
      mCurrentQueue.add( new float[] { points[0], points[1], radius, angle, left, top, right, bottom } );
    }

    synchronized public void pathEnd() {
      if ( !running || mCurrentQueue == null ) return;
      mCurrentQueue.end();
      mCurrentQueue = null;
    }

    public boolean isCompleted() {
      return mQueue.size() == 0;
    }

    public int getQueueSize() {
      return mQueue.size();
    }

    public void clear() {

      if ( running && mQueue != null ) {

        synchronized ( mQueue ) {
          while ( mQueue.size() > 0 ) {
            DrawQueue element = mQueue.poll();
            if ( null != element ) {
              mLogger.log( "end element..." );
              element.end();
            }
          }
        }
      }
    }

    /**
     * Ensure the drawing queue is completed
     */
    public void finish() {

      if ( running && mQueue != null ) {
        synchronized ( mQueue ) {
          Iterator<DrawQueue> iterator = mQueue.iterator();
          while ( iterator.hasNext() ) {
            DrawQueue element = iterator.next();
            if ( null != element ) {
              mLogger.log( "end element..." );
              element.end();
            }
          }
        }
      }
    }

    @Override
    public void run() {

      while ( !started ) {
        // wait until is not yet started
      }

      boolean s = false;

      float points[];
      float x, y, radius, angle;
      float left, top, right, bottom;

      mLogger.log( "thread.start!" );
      mLogger.log( "filter.init" );

      mFilter.init( mBitmap, mPreview );

      RectF invalidateRect = new RectF( 0, 0, mPreview.getWidth(), mPreview.getHeight() );
      RectF tempRect = new RectF();

      while ( running ) {

        if ( mQueue.size() > 0 && !isInterrupted() ) {

          mLogger.log( "queue.size: " + mQueue.size() );

          if ( !s ) {
            s = true;
            onProgressStart();
          }

          DrawQueue element = mQueue.element();

          if ( null == element ) {
            mQueue.poll();
            continue;
          }

          TiltShiftMode mode = element.mode_; // tilt shift mode
          mFilter.setTiltShiftMode( mode );

          while ( element.size() > 0 || !element.isCompleted() ) {
            if ( !running || isInterrupted() ) break;

            points = element.poll();
            if ( points == null ) continue;

            x = points[0];
            y = points[1];
            radius = points[2];
            angle = points[3];

            left = points[4];
            top = points[5];
            right = points[6];
            bottom = points[7];

            mFilter.tiltshift_draw( x, y, radius, angle );

            tempRect.set( left, top, right, bottom );

            // Log.d( getName(), "--------" );
            // Log.d( getName(), "previous rect: " + invalidateRect );
            // Log.d( getName(), "current  rect: " + tempRect );

            invalidateRect.union( tempRect );

            // Log.d( getName(), "union    rect: " + invalidateRect );

            mFilter.renderPreview( invalidateRect );

            invalidateRect.set( tempRect );

            mImageView.postInvalidate();

          }

          // now remove the element from the queue
          mQueue.poll();

        } else {
          if ( s ) {
            onProgressEnd();
            s = false;
          }
        }
      }

      onProgressEnd();
      mLogger.log( "thread.end" );
    };
  };

  /**
   * GenerateResultTask is used when the background draw operation is still running.
   * Just wait until the draw operation completed.
   */
  class GenerateResultTask extends AviaryAsyncTask<Void, Void, Void> {

    /** The m progress. */
    ProgressDialog mProgress = new ProgressDialog( getContext().getBaseContext() );

    @Override
    protected void PreExecute() {
      mProgress.setTitle( getContext().getBaseContext().getString( R.string.feather_loading_title ) );
      mProgress.setMessage( getContext().getBaseContext().getString( R.string.feather_effect_loading_message ) );
      mProgress.setIndeterminate( true );
      mProgress.setCancelable( false );
      mProgress.show();
    }

    @Override
    protected Void doInBackground( Void... params ) {

      if ( mBackgroundDrawThread != null ) {

        while ( mBackgroundDrawThread != null && !mBackgroundDrawThread.isCompleted() ) {
          mLogger.log( "waiting.... " + mBackgroundDrawThread.getQueueSize() );
          try {
            Thread.sleep( 50 );
          } catch ( InterruptedException e ) {
            e.printStackTrace();
          }
        }
      }

      mActions.add( mFilter.getActions().get( 0 ) );
      return null;
    }

    @Override
    protected void PostExecute( Void result ) {
      if ( getContext().getBaseActivity().isFinishing() ) return;

      if ( mProgress.isShowing() ) {
        try {
          mProgress.dismiss();
        } catch ( IllegalArgumentException e ) {
        }
      }

      onComplete( mPreview, mActions );
    }
  }
}




Java Source Code List

com.aviary.android.feather.AlertActivity.java
com.aviary.android.feather.AviaryMainController.java
com.aviary.android.feather.FeatherActivity.java
com.aviary.android.feather.async_tasks.AsyncImageManager.java
com.aviary.android.feather.async_tasks.DownloadImageAsyncTask.java
com.aviary.android.feather.async_tasks.ExifTask.java
com.aviary.android.feather.effects.AbstractContentPanel.java
com.aviary.android.feather.effects.AbstractOptionPanel.java
com.aviary.android.feather.effects.AbstractPanelLoaderService.java
com.aviary.android.feather.effects.AbstractPanel.java
com.aviary.android.feather.effects.AdjustEffectPanel.java
com.aviary.android.feather.effects.BordersPanel.java
com.aviary.android.feather.effects.ColorSplashPanel.java
com.aviary.android.feather.effects.CropPanel.java
com.aviary.android.feather.effects.DelayedSpotDrawPanel.java
com.aviary.android.feather.effects.DrawingPanel.java
com.aviary.android.feather.effects.EffectsPanel.java
com.aviary.android.feather.effects.EnhanceEffectPanel.java
com.aviary.android.feather.effects.MemePanel.java
com.aviary.android.feather.effects.NativeEffectRangePanel.java
com.aviary.android.feather.effects.SimpleStatusMachine.java
com.aviary.android.feather.effects.SliderEffectPanel.java
com.aviary.android.feather.effects.StickersPanel.java
com.aviary.android.feather.effects.TextPanel.java
com.aviary.android.feather.effects.TiltShiftPanel.java
com.aviary.android.feather.graphics.CdsPreviewTransformer.java
com.aviary.android.feather.graphics.GalleryBottomIndicatorDrawable.java
com.aviary.android.feather.graphics.GalleryTopIndicatorDrawable.java
com.aviary.android.feather.graphics.GlowBitmapDrawable.java
com.aviary.android.feather.graphics.GlowDrawable.java
com.aviary.android.feather.graphics.PluginDividerDrawable.java
com.aviary.android.feather.graphics.PreviewFillColorDrawable.java
com.aviary.android.feather.graphics.PreviewSpotDrawable.java
com.aviary.android.feather.graphics.RepeatableHorizontalDrawable.java
com.aviary.android.feather.opengl.AviaryGLSurfaceView.java
com.aviary.android.feather.utils.PackIconCallable.java
com.aviary.android.feather.utils.SimpleBitmapCache.java
com.aviary.android.feather.utils.ThreadUtils.java
com.aviary.android.feather.utils.TypefaceUtils.java
com.aviary.android.feather.utils.UIUtils.java
com.aviary.android.feather.widget.AdjustImageView.java
com.aviary.android.feather.widget.AviaryAbsSpinner.java
com.aviary.android.feather.widget.AviaryAdapterView.java
com.aviary.android.feather.widget.AviaryBadgeToolLayout.java
com.aviary.android.feather.widget.AviaryBottomBarViewFlipper.java
com.aviary.android.feather.widget.AviaryButton.java
com.aviary.android.feather.widget.AviaryEdgeEffect.java
com.aviary.android.feather.widget.AviaryGalleryTopIndicatorView.java
com.aviary.android.feather.widget.AviaryGallery.java
com.aviary.android.feather.widget.AviaryHighlightImageButton.java
com.aviary.android.feather.widget.AviaryImageRestoreSwitcher.java
com.aviary.android.feather.widget.AviaryImageSwitcher.java
com.aviary.android.feather.widget.AviaryNavBarViewFlipper.java
com.aviary.android.feather.widget.AviarySeekBar.java
com.aviary.android.feather.widget.AviaryTextView.java
com.aviary.android.feather.widget.AviaryToast.java
com.aviary.android.feather.widget.AviaryToggleButton.java
com.aviary.android.feather.widget.AviaryWheel.java
com.aviary.android.feather.widget.AviaryWorkspaceIndicator.java
com.aviary.android.feather.widget.AviaryWorkspace.java
com.aviary.android.feather.widget.CellLayout.java
com.aviary.android.feather.widget.CropImageView.java
com.aviary.android.feather.widget.DrawableHighlightView.java
com.aviary.android.feather.widget.EffectThumbLayout.java
com.aviary.android.feather.widget.HighlightView.java
com.aviary.android.feather.widget.IAPBuyButton.java
com.aviary.android.feather.widget.IAPDialogDetail.java
com.aviary.android.feather.widget.IAPDialogList.java
com.aviary.android.feather.widget.IAPDialogMain.java
com.aviary.android.feather.widget.ImageViewDrawableOverlay.java
com.aviary.android.feather.widget.ImageViewSpotDraw.java
com.aviary.android.feather.widget.ImageViewTiltiShiftTouch.java
com.aviary.android.feather.widget.ImageViewTouchAndDraw.java
com.aviary.android.feather.widget.PointCloud.java
com.aviary.android.feather.widget.ScrollerRunnable.java
com.aviary.android.feather.widget.VibrationHelper.java
com.aviary.android.feather.widget.VibrationWidget.java