gpt4 book ai didi

android - 混合来自两个位图的像素

转载 作者:可可西里 更新时间:2023-11-01 18:45:45 30 4
gpt4 key购买 nike

我在这里用头撞墙,我相当确定我在做一些愚蠢的事情,所以是时候公开我的愚蠢了。

我正在尝试拍摄两张图像,然后使用标准混合算法(强光、柔光、叠加、乘法等)将它们混合成第三张图像。

因为 Android 没有内置这样的混合属性,所以我沿着获取每个像素的路径并使用算法将它们组合起来。然而,结果是垃圾。以下是简单乘法混合的结果(使用的图像和预期结果)。

基地:alt text

混合:alt text

预期结果:alt text

垃圾结果:alt text

如有任何帮助,我们将不胜感激。下面是代码,我试图去掉所有的“垃圾”,但有些可能已经通过了。如果有什么不清楚的,我会清理它。

    ImageView imageView = (ImageView) findViewById(R.id.ImageView01);
Bitmap base = BitmapFactory.decodeResource(getResources(), R.drawable.base);
Bitmap result = base.copy(Bitmap.Config.RGB_565, true);
Bitmap blend = BitmapFactory.decodeResource(getResources(), R.drawable.blend);

IntBuffer buffBase = IntBuffer.allocate(base.getWidth() * base.getHeight());
base.copyPixelsToBuffer(buffBase);
buffBase.rewind();

IntBuffer buffBlend = IntBuffer.allocate(blend.getWidth() * blend.getHeight());
blend.copyPixelsToBuffer(buffBlend);
buffBlend.rewind();

IntBuffer buffOut = IntBuffer.allocate(base.getWidth() * base.getHeight());
buffOut.rewind();

while (buffOut.position() < buffOut.limit()) {
int filterInt = buffBlend.get();
int srcInt = buffBase.get();

int redValueFilter = Color.red(filterInt);
int greenValueFilter = Color.green(filterInt);
int blueValueFilter = Color.blue(filterInt);

int redValueSrc = Color.red(srcInt);
int greenValueSrc = Color.green(srcInt);
int blueValueSrc = Color.blue(srcInt);

int redValueFinal = multiply(redValueFilter, redValueSrc);
int greenValueFinal = multiply(greenValueFilter, greenValueSrc);
int blueValueFinal = multiply(blueValueFilter, blueValueSrc);

int pixel = Color.argb(255, redValueFinal, greenValueFinal, blueValueFinal);

buffOut.put(pixel);
}

buffOut.rewind();

result.copyPixelsFromBuffer(buffOut);

BitmapDrawable drawable = new BitmapDrawable(getResources(), result);
imageView.setImageDrawable(drawable);
}

int multiply(int in1, int in2) {
return in1 * in2 / 255;
}

最佳答案

重现后,我认为您的问题与在 RGB565 模式下处理图像有关。正如在 this post 中讨论的那样,位图显然需要处于 ARGB8888 模式才能正确操作。我首先通过执行以下操作获得了乘法混合的预期结果:

Resources res = getResources();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap base = BitmapFactory.decodeResource(res, R.drawable.base, options);
Bitmap blend = BitmapFactory.decodeResource(res, R.drawable.blend, options);

// now base and blend are in ARGB8888 mode, which is what you want

Bitmap result = base.copy(Config.ARGB_8888, true);
// Continue with IntBuffers as before...

将位图转换为 ARGB8888 模式似乎对我有用,至少对于渐变测试模式而言。但是,如果你只需要做 Screen 或 Multiply,你也可以试试这个:

// Same image creation/reading as above, then:
Paint p = new Paint();
p.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY));
p.setShader(new BitmapShader(blend, TileMode.CLAMP, TileMode.CLAMP));

Canvas c = new Canvas();
c.setBitmap(result);
c.drawBitmap(base, 0, 0, null);
c.drawRect(0, 0, base.getWidth(), base.getHeight(), p);

有了它,您就不会进行每像素计算,但您只能使用预设的 PorterDuff.Mode。在我的快速(和肮脏的)测试中,这是我能够在非渐变图像上进行混合的唯一方法。

关于android - 混合来自两个位图的像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4605325/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com