| /* |
| * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following |
| * disclaimer in the documentation and/or other materials provided |
| * with the distribution. |
| * * Neither the name of The Linux Foundation nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| package com.android.gallery3d.filtershow.filters; |
| |
| import android.app.ProgressDialog; |
| import android.graphics.Bitmap; |
| import android.util.Log; |
| import android.view.View; |
| import android.widget.SeekBar; |
| import android.widget.Toast; |
| |
| import org.codeaurora.gallery.R; |
| import com.android.gallery3d.app.GalleryActivity; |
| import com.android.gallery3d.filtershow.FilterShowActivity; |
| import com.android.gallery3d.filtershow.controller.Parameter; |
| import com.android.gallery3d.filtershow.editors.TrueScannerEditor; |
| import com.android.gallery3d.filtershow.imageshow.ImageTrueScanner; |
| import com.android.gallery3d.filtershow.imageshow.MasterImage; |
| import com.android.gallery3d.ui.MenuExecutor; |
| import static com.android.gallery3d.filtershow.imageshow.ImageTrueScanner.*; |
| |
| public class TrueScannerActs extends SimpleImageFilter { |
| public static final String SERIALIZATION_NAME = "TrueScannerActs"; |
| //The minimum resolution that TrueScanner library supports is VGA, i.e. 640x480. |
| public static final int MIN_WIDTH = 640; |
| public static final int MIN_HEIGHT = 480; |
| private static boolean rotating = false; |
| private static final boolean DEBUG = false; |
| private static boolean isTrueScannerEnabled = true; |
| private static boolean isPointsAcquired; |
| private final static int POINTS_LEN = 8; |
| private static int[] mAcquiredPoints = new int[POINTS_LEN+2]; |
| protected boolean isWhiteBoard = false; |
| private boolean mLocked = false; |
| private Bitmap rectifiedImage = null; |
| private int[] oldPts = new int[POINTS_LEN]; |
| private ProgressDialog mProgressDialog; |
| |
| private void printDebug(String str) { |
| if(DEBUG) |
| android.util.Log.d("TrueScanner", str); |
| } |
| |
| public static boolean isTrueScannerEnabled() { |
| return isTrueScannerEnabled; |
| } |
| |
| public static boolean setRotating(boolean isRotating) { |
| return rotating = isRotating; |
| } |
| |
| public TrueScannerActs() { |
| mName = "TrueScannerActs"; |
| isPointsAcquired = false; |
| } |
| |
| public FilterRepresentation getDefaultRepresentation() { |
| FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation(); |
| representation.setName("TrueScanner"); |
| representation.setSerializationName(SERIALIZATION_NAME); |
| representation.setFilterClass(TrueScannerActs.class); |
| representation.setTextId(R.string.truescanner_normal); |
| representation.setMinimum(0); |
| representation.setMaximum(10); |
| representation.setValue(0); |
| representation.setDefaultValue(0); |
| representation.setSupportsPartialRendering(false); |
| representation.setEditorId(TrueScannerEditor.ID); |
| |
| return representation; |
| } |
| |
| private native int[] processImage(Bitmap orgBitmap, Bitmap rectifiedBitmap, int[] cornerPts); |
| private native int enhanceImage(Bitmap orgBitmap, Bitmap rectifiedBitmap); |
| |
| private synchronized boolean acquireLock(boolean isAcquiring) { |
| if(mLocked != isAcquiring) { |
| mLocked = isAcquiring; |
| return true; |
| } |
| return false; |
| } |
| |
| private void showProgressDialog() { |
| if (null != sActivity) { |
| sActivity.runOnUiThread(new Runnable() { |
| public void run() { |
| if (!sActivity.isFinishing()) { |
| mProgressDialog = ProgressDialog.show(sActivity, |
| "", "Processing...", true, false); |
| mProgressDialog.show(); |
| } |
| } |
| }); |
| } |
| } |
| |
| private void dismissProgressDialog() { |
| if (null != sActivity) { |
| sActivity.runOnUiThread(new Runnable() { |
| public void run() { |
| if (mProgressDialog != null && mProgressDialog.isShowing()) { |
| mProgressDialog.dismiss(); |
| mProgressDialog = null; |
| } |
| } |
| }); |
| } |
| } |
| |
| @Override |
| public Bitmap apply(Bitmap bitmap, float not_use, int quality) { |
| if(bitmap == null) |
| return null; |
| int w = bitmap.getWidth(); |
| int h = bitmap.getHeight(); |
| if (w < h) { |
| w = h; |
| h = bitmap.getWidth(); |
| } |
| if(w <= MIN_WIDTH || h <= MIN_HEIGHT) |
| return bitmap; |
| if(ImageTrueScanner.getCordsUIState()) { |
| return bitmap; |
| } |
| if(!acquireLock(true)) { |
| showToast("Still processing the previous request... ", Toast.LENGTH_LONG); |
| return bitmap; |
| } |
| new Throwable().printStackTrace(); |
| int[] pts = ImageTrueScanner.getDeterminedPoints(); |
| int[] resultPts = new int[POINTS_LEN]; |
| float xScale = ((float)bitmap.getWidth())/pts[POINTS_LEN]; |
| float yScale = ((float)bitmap.getHeight())/pts[POINTS_LEN+1]; |
| for(int i=0; i < POINTS_LEN; i++) { |
| if(i%2 == 0) |
| resultPts[i] = (int)((pts[i] - pts[POINTS_LEN+2])*xScale); |
| else |
| resultPts[i] = (int)((pts[i] - pts[POINTS_LEN+3])*yScale); |
| } |
| if (rotating && rectifiedImage != null) { |
| acquireLock(false); |
| rotating = false; |
| return rectifiedImage; |
| } |
| rectifiedImage = Bitmap.createBitmap( |
| bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); |
| int[] outputSize = processImage(bitmap, rectifiedImage, resultPts); |
| rectifiedImage = Bitmap.createBitmap( |
| rectifiedImage, 0, 0, outputSize[0], outputSize[1]); |
| if(ImageTrueScanner.getRemoveGlareButtonStatus()) { |
| Bitmap enhancedImage = Bitmap.createBitmap( |
| outputSize[0], outputSize[1], Bitmap.Config.ARGB_8888); |
| showProgressDialog(); |
| enhanceImage(rectifiedImage, enhancedImage); |
| dismissProgressDialog(); |
| rectifiedImage = enhancedImage; |
| } |
| acquireLock(false); |
| |
| return rectifiedImage; |
| } |
| |
| static { |
| try { |
| System.loadLibrary("jni_truescanner_v2"); |
| isTrueScannerEnabled = true; |
| } catch(UnsatisfiedLinkError e) { |
| isTrueScannerEnabled = false; |
| } |
| } |
| } |