| package com.android.rs.refocus.f32; |
| |
| |
| import com.android.rs.refocus.BlurStack; |
| import com.android.rs.refocus.KernelDataForRenderScript; |
| import com.android.rs.refocus.LayerInfo; |
| import com.android.rs.refocus.MediaStoreSaver; |
| import com.android.rs.refocus.R; |
| import com.android.rs.refocus.RefocusFilter; |
| import com.android.rs.refocus.renderscript.ScriptC_layered_filter_fast_f32; |
| |
| import android.graphics.Bitmap; |
| import android.support.v8.renderscript.Allocation; |
| import android.support.v8.renderscript.RenderScript; |
| import android.support.v8.renderscript.Script; |
| import android.util.Log; |
| /** |
| * An accelerated implementation of RefocusFilter using float32 as pixel |
| * representation. The corresponding RenderScript class is |
| * ScriptC_layered_filter_f32. Integral image is used for the speedup. |
| * |
| * Example Usage: |
| * |
| * {@code RenderScript renderScript = RenderScript.create(context);} |
| * {@code RefocusFilterF32 rfFilter = new RefocusFilterF32(renderScript);} |
| * {@code ProgressCallback progress;} |
| * {@code Bitmap result = rfFilter.compute(rgbdImage, blurStack, progress);} |
| * |
| * @author zhl@google.com (Li Zhang) |
| */ |
| public class RefocusFilterF32 extends |
| RefocusFilter<ScriptC_layered_filter_fast_f32> { |
| private static final String myTAG = "RefocusFilterF32"; |
| private static final boolean ENABLE_FAST_FILTER = true; |
| private static final float MIN_DISC_RADIUS_FOR_FAST_FILTER = 3; |
| boolean useFastFilterForCurrentLayer = false; |
| ImageBuffersForRenderScriptF32 buffers; |
| |
| public RefocusFilterF32(RenderScript rs) { |
| super(rs); |
| } |
| |
| @Override |
| protected void initializeScriptAndBuffers(Bitmap inputImage, |
| LayerInfo focalLayer) { |
| scriptC = new ScriptC_layered_filter_fast_f32(renderScript); |
| |
| // Allocates, binds, and initializes buffers that interface between Java |
| // and Render Script. |
| // + 1 is for the boundary case of using integral image. |
| KernelDataForRenderScript.setUseNewRS(false); |
| int margin = KernelDataForRenderScript.getMaxKernelRadius() + 1; |
| buffers = new ImageBuffersForRenderScriptF32(inputImage, margin, |
| renderScript, scriptC); |
| buffers.initializeRenderScript(focalLayer, scriptC); |
| } |
| |
| @Override |
| protected Bitmap extractResultImage() { |
| // Extracts the result from .rs file to {@code buffers.outputImage} in Java. |
| long startnow; |
| long endnow; |
| startnow = System.nanoTime(); |
| scriptC.forEach_PackOutputImage(buffers.outAllocation); |
| endnow = System.nanoTime(); |
| Log.d(myTAG, "PackOutputImage: "+(endnow - startnow)+ " ns" ); |
| |
| buffers.outAllocation.copyTo(buffers.outputImage); |
| return buffers.outputImage; |
| } |
| |
| /* |
| * Utility Method to extract intermediatory result |
| */ |
| private void extractSharpImage(String name) { |
| |
| Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(), |
| buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888); |
| Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap); |
| scriptC.forEach_PackSharpImage(mAllocation); |
| |
| mAllocation.copyTo(mBitmap); |
| MediaStoreSaver.savePNG(mBitmap, "sharpF32", name, renderScript.getApplicationContext()); |
| } |
| /* |
| * Utility Method to extract intermediatory result |
| */ |
| private void extractFuzzyImage(String name) { |
| |
| Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(), |
| buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888); |
| Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap); |
| scriptC.forEach_PackFuzzyImage(mAllocation); |
| |
| mAllocation.copyTo(mBitmap); |
| MediaStoreSaver.savePNG(mBitmap, "fuzzyF32", name, renderScript.getApplicationContext()); |
| } |
| |
| @Override |
| protected void setTargetLayer(LayerInfo layerInfo) { |
| scriptC.invoke_SetTargetLayer(layerInfo.frontDepth, layerInfo.backDepth); |
| } |
| |
| @Override |
| protected void setBlendInfo(int dilationRadius) { |
| scriptC.invoke_SetBlendInfo(dilationRadius); |
| } |
| |
| @Override |
| protected void setKernelData(int targetLayer, BlurStack blurStack) { |
| KernelDataForRenderScriptF32 kernelData = |
| new KernelDataForRenderScriptF32(targetLayer, blurStack, renderScript); |
| |
| if (ENABLE_FAST_FILTER |
| && kernelData.minDiskRadius > MIN_DISC_RADIUS_FOR_FAST_FILTER) { |
| useFastFilterForCurrentLayer = true; |
| } else { |
| useFastFilterForCurrentLayer = false; |
| } |
| |
| scriptC.bind_g_kernel_info(kernelData.getKernelInfo()); |
| scriptC.bind_g_kernel_stack(kernelData.stackAllocation); |
| } |
| |
| @Override |
| protected void computeLayerMatteBehindFocalDepth() { |
| // Marks active pixels (pixels that are on this target layer); |
| // Marks adjacent pixels that are close enough to active pixels; |
| long startnow; |
| long endnow; |
| startnow = System.nanoTime(); |
| scriptC.forEach_MarkLayerMask(buffers.inAllocation); |
| endnow = System.nanoTime(); |
| Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" ); |
| |
| startnow = System.nanoTime(); |
| scriptC.forEach_ComputeLayerMatteBehindFocalDepth(buffers.inAllocation); |
| endnow = System.nanoTime(); |
| Log.d(myTAG, "ComputeLayerMatteBehindFocalDepth: "+(endnow - startnow)+ " ns" ); |
| } |
| |
| @Override |
| protected void filterLayerBehindFocalDepth() { |
| // Filters the target layer and saves the result to {@code g_accum_map} in |
| // .rs file. |
| long startnow; |
| long endnow; |
| if (useFastFilterForCurrentLayer) { |
| scriptC.invoke_SetUseIntegralImage(1); |
| Script.LaunchOptions launchOptions = new Script.LaunchOptions(); |
| launchOptions.setX(0, 1); |
| launchOptions.setY(0, buffers.inputImage.getHeight()); |
| |
| startnow = System.nanoTime(); |
| scriptC.forEach_ComputeIntegralImageForLayerBehindFocalDepth( |
| buffers.inAllocation, launchOptions); |
| endnow = System.nanoTime(); |
| Log.d(myTAG, "ComputeIntegralImageForLayerBehindFocalDepth: "+(endnow - startnow)+ " ns" ); |
| } else { |
| scriptC.invoke_SetUseIntegralImage(0); |
| } |
| |
| startnow = System.nanoTime(); |
| scriptC.forEach_FilterLayerBehindFocalDepth(buffers.inAllocation); |
| endnow = System.nanoTime(); |
| Log.d(myTAG, "FilterLayerBehindFocalDepth: "+(endnow - startnow)+ " ns" ); |
| |
| //extractFuzzyImage("fuzzy_behind"); |
| //extractSharpImage("sharp_behind"); |
| } |
| |
| @Override |
| protected void updateSharpImageUsingFuzzyImage() { |
| // Log the kernel execution time |
| long startnow; |
| long endnow; |
| startnow = System.nanoTime(); |
| scriptC.forEach_UpdateSharpImageUsingFuzzyImage(buffers.inAllocation); |
| endnow = System.nanoTime(); |
| Log.d(myTAG, "UpdateSharpImageUsingFuzzyImage: "+(endnow - startnow)+ " ns" ); |
| |
| //extractSharpImage("sharp_update"); |
| } |
| |
| @Override |
| protected void computeLayerMatteInFrontOfFocalDepth() { |
| // Marks active pixels (pixels that are on this target layer); |
| // Marks adjacent pixels that are close enough to active pixels; |
| long startnow; |
| long endnow; |
| startnow = System.nanoTime(); |
| scriptC.forEach_MarkLayerMask(buffers.inAllocation); |
| endnow = System.nanoTime(); |
| Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" ); |
| |
| startnow = System.nanoTime(); |
| scriptC.forEach_ComputeLayerMatteInFrontOfFocalDepth(buffers.inAllocation); |
| endnow = System.nanoTime(); |
| Log.d(myTAG, "ComputeLayerMatteInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" ); |
| } |
| |
| @Override |
| protected void filterLayerInFrontOfFocalDepth() { |
| // Filters the target layer and accumulates the result to {@code |
| // g_accum_map} in .rs file. |
| long startnow; |
| long endnow; |
| if (useFastFilterForCurrentLayer) { |
| scriptC.invoke_SetUseIntegralImage(1); |
| Script.LaunchOptions launchOptions = new Script.LaunchOptions(); |
| launchOptions.setX(0, 1); |
| launchOptions.setY(0, buffers.inputImage.getHeight()); |
| |
| startnow = System.nanoTime(); |
| scriptC.forEach_ComputeIntegralImageForLayerInFrontOfFocalDepth( |
| buffers.inAllocation, launchOptions); |
| endnow = System.nanoTime(); |
| Log.d(myTAG, "ComputeIntegralImageForLayerInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" ); |
| } else { |
| scriptC.invoke_SetUseIntegralImage(0); |
| } |
| startnow = System.nanoTime(); |
| scriptC.forEach_FilterLayerInFrontOfFocalDepth(buffers.inAllocation); |
| endnow = System.nanoTime(); |
| Log.d(myTAG, "FilterLayerInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" ); |
| |
| //extractFuzzyImage("fuzzy_front"); |
| //extractSharpImage("sharp_front"); |
| } |
| |
| @Override |
| protected void finalizeFuzzyImageUsingSharpImage() { |
| // Blends {@code g_accum_map} and {@code g_focus_map} in .rs file. |
| // Saves the result in {@code g_accum_map}. |
| long startnow; |
| long endnow; |
| startnow = System.nanoTime(); |
| scriptC.forEach_FinalizeFuzzyImageUsingSharpImage(buffers.inAllocation); |
| endnow = System.nanoTime(); |
| Log.d(myTAG, "FinalizeFuzzyImageUsingSharpImage: "+(endnow - startnow)+ " ns" ); |
| } |
| } |