简体   繁体   English

使用Android处理1920x1280图像-RenderScript

[英]Processing 1920x1280 image with Android - RenderScript

I am newbie to RenderScript and trying to process image with size 1920x1280px, this seems to be crashing every time with following error on logcat 我是RenderScript的新手,并尝试处理尺寸为1920x1280px的图像,这似乎每次都崩溃,并且在logcat上出现以下错误

09-04 19:26:04.670: D/dalvikvm(30308): GC_FOR_ALLOC freed 73K, 3% free 6615K/6787K, paused 26ms
09-04 19:26:04.680: I/dalvikvm-heap(30308): Grow heap (frag case) to 14.404MB for 8294416-byte allocation
09-04 19:26:04.690: D/dalvikvm(30308): GC_CONCURRENT freed 2K, 2% free 14713K/14919K, paused 1ms+1ms
09-04 19:26:04.820: D/dalvikvm(30308): GC_FOR_ALLOC freed 0K, 2% free 14713K/14919K, paused 12ms
09-04 19:26:04.820: I/dalvikvm-heap(30308): Grow heap (frag case) to 17.917MB for 3686416-byte allocation
09-04 19:26:04.840: D/dalvikvm(30308): GC_FOR_ALLOC freed 0K, 2% free 18313K/18567K, paused 13ms
09-04 19:26:04.860: D/dalvikvm(30308): GC_CONCURRENT freed 0K, 2% free 18313K/18567K, paused 1ms+2ms
09-04 19:26:05.010: A/libc(30308): Fatal signal 11 (SIGSEGV) at 0x5c41f809 (code=1)
09-04 19:26:05.010: A/libc(30308): Fatal signal 11 (SIGSEGV) at 0x5c41e001 (code=1)

where as the same code works if I resize the image to 100x56px :-(. 如果将图像尺寸调整为100x56px :-(

Please review the code below and suggest me any changes that needs to be done, the code is based on the example I found elsewhere on internet and from sample. 请查看下面的代码,并向我建议需要做的任何更改,这些代码基于我在Internet上其他地方找到的示例和示例。

NOTE: The code below is not really production quality. 注意:以下代码不是真正的生产质量。

content of VDRender.rs VDRender.rs的内容

#pragma version(1)
#pragma rs java_package_name(com.iangclifton.tutorials.renderscript);

#include "rs_graphics.rsh"

const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};

void root(const uchar4 *v_in, uchar4 *v_out) {

    //rsDebug("Called ROOT - ONE", rsUptimeMillis());

    float4 f4 = rsUnpackColor8888(*v_in);

    float3 mono = dot(f4.rgb, gMonoMult);
    *v_out = rsPackColorTo8888(mono);
}

content of RenderScript101.rs RenderScript101.rs的内容

#pragma version(1)
#pragma rs java_package_name(com.iangclifton.tutorials.renderscript);

#include "rs_graphics.rsh"

float4 gBgColor; // Background color as xyzw 4-part float
rs_allocation gBgImage; // Background image
rs_allocation gVDBgImage; // Background image

rs_sampler gLinearClamp; // Sampler used by the program fragment
rs_program_fragment gSingleTextureFragmentProgram; // fragment shader
rs_program_store gProgramStoreBlendNone; // blend none, depth none program store
rs_program_vertex gProgramVertex; // Default vertex shader

rs_script gVDScript;

static const float3 gBgVertices[4] = {
    { -1.0, -1.0, -1.0 },
    { 1.0, -1.0, -1.0 },
    { 1.0, 1.0, -1.0 },
    {-1.0, 1.0, -1.0 }
};

void drawInteger(int value, int x, int y) {

    char text[50] = "0";
    int index = 0;

    if(value != 0) {

    index = 49;
    text[index] = 0;

    while(value > 0) {

        index--;

        int digitValue = value % 10;

        text[index] = '0' + digitValue;

        value /= 10;
    }

    if(value < 0) {
        text[index--] = '-';
    }    
    }

    rsgDrawText(&text[index], x, y);
}

int64_t gTimeMS = 0;
int64_t updateFPS = 0;

int gFPS = 0;

static void drawBackground() {

    if (gBgImage.p != 0) {

        //rsgClearColor(gBgColor.x, gBgColor.y, gBgColor.z, gBgColor.w);

        rs_matrix4x4 projection, model;
        rsMatrixLoadOrtho(&projection, -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f);
        rsgProgramVertexLoadProjectionMatrix(&projection);

        rsMatrixLoadIdentity(&model);
        rsgProgramVertexLoadModelMatrix(&model);

        // ----
        if(1) 
        {
            rsForEach(gVDScript, gBgImage, gBgImage, NULL);
            rsgBindTexture(gSingleTextureFragmentProgram, 0, gBgImage);
        }
        else
        {
            rsgBindTexture(gSingleTextureFragmentProgram, 0, gBgImage);
        }
        //----

        rsgDrawQuad(
            gBgVertices[0].x, gBgVertices[0].y, gBgVertices[0].z,
            gBgVertices[1].x, gBgVertices[1].y, gBgVertices[0].z,
            gBgVertices[2].x, gBgVertices[2].y, gBgVertices[0].z,
            gBgVertices[3].x, gBgVertices[3].y, gBgVertices[0].z
        );

        int x = 250;
        int y = 150;
        int fps = 0;

        int64_t t = rsUptimeMillis();
        int diff = t - gTimeMS;
        fps = 1000 / diff; 
        gTimeMS = t;

        if((t - updateFPS) > 500)
        {   
            gFPS = fps;
            updateFPS = t;
        }

        rsgDrawText("FPS:", x, y);
        drawInteger(gFPS, 250+40, 150);
    }
}

void init() {
    gBgColor = (float4) { 0.0f, 1.0f, 0.0f, 1.0f };
    rsDebug("Called init", rsUptimeMillis());
}

int root() {
    rsgBindProgramVertex(gProgramVertex);
    rsgBindProgramFragment(gSingleTextureFragmentProgram);
    rsgBindProgramStore(gProgramStoreBlendNone);

    drawBackground();
    return 1;
}

content of RenderScript101RS.java RenderScript101RS.java的内容

package com.iangclifton.tutorials.renderscript;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.renderscript.Allocation;
import android.renderscript.Float4;
import android.renderscript.Matrix4f;
import android.renderscript.ProgramFragment;
import android.renderscript.ProgramFragmentFixedFunction;
import android.renderscript.ProgramStore;
import android.renderscript.ProgramVertex;
import android.renderscript.ProgramVertexFixedFunction;
import android.renderscript.RenderScriptGL;
import android.renderscript.Sampler;

/**
 * Custom RenderScript helper that simplifies interaction with the RenderScript.
 * 
 * @author Ian G. Clifton
 */
public class RenderScript101RS {

    private Sampler mLinearClamp;
    private ProgramStore mProgramStoreBlendNone;
    private ProgramVertex mProgramVertex;
    private RenderScriptGL mRS;
    private ScriptC_RenderScript101 mScript;
    private ScriptC_VDRender mVDScript;
    private ProgramFragment mSingleTextureFragmentProgram;

    /**
     * Constructs a new helper with RenderScriptGL and Resources references.
     * 
     * @param rs RenderScriptGL reference
     * @param res Resources reference
     * @param resId int ID of the RenderScript (e.g., R.raw.xyz)
     */
    public RenderScript101RS(RenderScriptGL rs, Resources res, int resId, int resId2) {
        mRS = rs;

        mScript = new ScriptC_RenderScript101(rs, res, resId);
        mVDScript = new ScriptC_VDRender(rs, res, resId2);

        mScript.set_gVDScript(mVDScript);

        initProgramStore();
        initSampler();
        initProgramFragment();
        initProgramVertex();
        mRS.bindRootScript(mScript);

    }

    /**
     * Sets a custom background Bitmap on the RenderScript view
     * 
     * @param bitmap Bitmap to use as the background
     */
    public void setBackgroundBitmap(Bitmap bitmap) {
        if (bitmap == null) {
            return;
        }
        final Allocation bitmapAllocation = Allocation.createFromBitmap(mRS, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE);
        mScript.set_gBgImage(bitmapAllocation);

        //final Allocation bitmapVDAllocation = Allocation.createFromBitmap(mRS, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE);
        //mScript.set_gVDBgImage(bitmapVDAllocation);
    }

    /**
     * Sets a custom background color on the RenderScript view
     * 
     * @param color Float4 color
     */
    public void setBackgroundColor(Float4 color) {
        mScript.set_gBgColor(color);
    }

    /**
     * Prepares the ProgramFragment (fragment shader)
     */
    private void initProgramFragment() {
        final ProgramFragmentFixedFunction.Builder pfBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
        pfBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
        mSingleTextureFragmentProgram = pfBuilder.create();
        mScript.set_gSingleTextureFragmentProgram(mSingleTextureFragmentProgram);
    }

    /**
     * Prepares the ProgramStore (controls use of framebuffer such as blending)
     */
    private void initProgramStore() {
        mProgramStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(mRS);
        mScript.set_gProgramStoreBlendNone(mProgramStoreBlendNone);
    }

    /**
     * Prepares the ProgramVertex (vertex shader)
     */
    private void initProgramVertex() {
        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
        mProgramVertex = pvb.create();
        ProgramVertexFixedFunction.Constants pva = new ProgramVertexFixedFunction.Constants(mRS);
        ((ProgramVertexFixedFunction) mProgramVertex).bindConstants(pva);
        Matrix4f proj = new Matrix4f();
        proj.loadProjectionNormalized(1, 1);
        pva.setProjection(proj);
        mScript.set_gProgramVertex(mProgramVertex);
    }

    /**
     * Prepares the Sampler (controls how pixels are pulled from a texture)
     */
    private void initSampler() {
        mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
        mScript.set_gLinearClamp(mLinearClamp);
    }
}

content of RenderScript101View RenderScript101View的内容

package com.iangclifton.tutorials.renderscript;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.renderscript.RSSurfaceView;
import android.renderscript.RenderScriptGL;
import android.view.MotionEvent;

/**
 * Custom RSSurfaceView that sets up the RenderScript and captures touch events.
 * 
 * @author Ian G. Clifton
 */
public class RenderScript101View extends RSSurfaceView {
    private Context mContext;
    private RenderScript101RS mRenderScript;
    private RenderScriptGL mRS;

    /**
     * {@inheritDoc}}
     */
    public RenderScript101View(Context context) {
        super(context);
        mContext = context;
        ensureRenderScript();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);

        if (mRenderScript == null) {
            return true;
        }

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            mRenderScript.setBackgroundBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.icon00072half));
        }

        return true;
    }

    /**
     * Ensures the RenderScriptGL reference has been established and our custom
     * RS helper has been created.
     */
    private void ensureRenderScript() {
        if (mRS == null) {
            final RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
            mRS = createRenderScriptGL(sc);
        }
        if (mRenderScript == null) {
            mRenderScript = new RenderScript101RS(mRS, mContext.getResources(), R.raw.renderscript101, R.raw.vdrender);
        }
    }
}

There is no exception or warning in your LogCat but I may know the issue. LogCat中没有异常或警告,但我可能知道此问题。

First off, I didn't even look at your RenderScript because you said it works fine for small bitmap. 首先,我什至没有看过您的RenderScript,因为您说过,它对于小位图非常有用。

In android each VM or process have its own portion of memory and this is mostly not enough for a bitmap 1920x1080. 在android中,每个VM或进程都有其自己的内存部分,而对于1920x1080的位图而言,这几乎是不够的。 So your logcat should have prompt something like this that you may have neglected: 因此,您的logcat应该提示您可能忽略了以下内容:

bitmap size exceeds VM budget

I don't know your implementation details (getting bitmap form server, local file etc.). 我不知道您的实现细节(获取位图表单服务器,本地文件等)。 So I will guide you to Android Bitmap Training . 因此,我将指导您进行Android位图培训

The general idea is to load image as small as you need. 通常的想法是加载所需大小的图像。 By this: 这样:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

The crucial part: 关键部分:

options.inJustDecodeBounds = true;

Says hey! 说嘿! don't decode and load the bitmap yet. 不要解码并加载位图。 I will do some settings to my Bitmap. 我将对我的位图进行一些设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM