3

画像彩度フィルターには2つの意味があります。1つはJavaを使用し、もう1つはRenderscriptを使用します。実際、私のネクサス4デバイスではrenderscriptが遅いのですが、どうすればよいですか?

Javaの実装:

public final void Saturation(Bitmap canvas, int saturation, boolean accumulate, int imageNumber)
{
    int height = canvas.getHeight();
    int width = canvas.getWidth();
    int[] pixels = new int[height*width];
    int[] resultPixels = new int[height*width];
    canvas.getPixels(pixels, 0, width, 0, 0, width, height);

    if (!accumulate)
    {
        for (int i = 0; i < pixels.length; i ++)
        {
            int red = Color.red(pixels[i]);
            int green = Color.green(pixels[i]);
            int blue = Color.blue(pixels[i]);

            double t = (double)red * 0.11 + (double)green * 0.59 + (double)blue * 0.3;
            red = (int)Math.round(Math.min((double)red + (t - (double)red) * saturation / 100.0, 255));
            green = (int)Math.round(Math.min((double)green + (t - (double)green) * saturation / 100.0, 255));
            blue = (int)Math.round(Math.min((double)blue + (t - (double)blue) * saturation / 100.0, 255));

            resultPixels[i] = Color.argb(Color.alpha(pixels[i]), red, green, blue);
        }
    }

    canvas.setPixels(resultPixels, 0, width, 0, 0, width, height);
}

Renderscriptの実装:

Java部分:

public static Bitmap saturate(Bitmap bmIn, float saturation, Context context, Resources resources)
{
    Bitmap bmOut = Bitmap.createBitmap(bmIn.getWidth(), bmIn.getHeight(),
            bmIn.getConfig());
    RenderScript rs = RenderScript.create(context);
    Allocation allocIn;
    allocIn = Allocation.createFromBitmap(rs, bmIn,
            Allocation.MipmapControl.MIPMAP_NONE,
            Allocation.USAGE_SCRIPT);
    Allocation allocOut = Allocation.createTyped(rs, allocIn.getType());
    ScriptC_saturation script = new ScriptC_saturation(rs, resources,
            R.raw.saturation);
    script.set_in(allocIn);
    script.set_out(allocOut);
    script.set_script(script);
    script.set_saturation(saturation);
    script.invoke_filter();
    allocOut.copyTo(bmOut);
    return bmOut;
}

Renderscriptスクリプト:

#pragma version(1)
#pragma rs java_package_name(ca.tutortutor.embossimage)

rs_allocation out;
rs_allocation in;
rs_script script;
float saturation;

void root(const uchar4* v_in, uchar4* v_out, const void* usrData, uint32_t x,
      uint32_t y)
{
    float4 current = rsUnpackColor8888(*v_in);

    float t = current.r * 0.11f + current.g * 0.59f + current.b * 0.3f;
    rsDebug("renderscript t = ", t);
    rsDebug("renderscript red before = ", current.r);
    current.r = fmin(current.r + (t - current.r) * saturation / 100.0f, 1.f);
    current.g = fmin(current.g + (t - current.g) * saturation / 100.0f, 1.f);
    current.b = fmin(current.b + (t - current.b) * saturation / 100.0f, 1.f);
    rsDebug("renderscript red after = ", current.r);

    *v_out = rsPackColorTo8888(current.r, current.g, current.b, current.a);
}

void filter()
{
    rsDebug("RS_VERSION = ", RS_VERSION);
    #if !defined(RS_VERSION) || (RS_VERSION < 14)
        rsForEach(script, in, out, 0);
    #else
        rsForEach(script, in, out);
    #endif
}

renderscriptはcpuとネイティブコードの4つのコアすべてを使用する必要があり、Android 4.2.2ではgpuコアである可能性があるため、javaよりもはるかに高速である必要があると思いました。

4

1 に答える 1

9

Renderscript コードが rsDebug() を使用してログに出力されていることがすぐにわかりますが、これは遅いことが保証されています。ロギング コードを削除して、タイミングを再度測定してみてください。この場合、Nexus 4 は 4 つの CPU スレッドで実行する必要があります。現在、Nexus 4 での GPU サポートはありません。

于 2013-03-16T22:18:51.937 に答える