我试图实现一个简单的动作,即改变普通位图的颜色。 不幸的是,出现了一些错误。在我的情况下,我想要一个灰色钢的位图变成更红的钢。因此,我编写了一些代码,它获取每个像素的颜色int并为每个像素提高红色值。现在发生了两件事: 首先,即使我使用AsyncTask,转换所有像素也需要很长很长时间。 其次,当它完成一个循环时,整个位图类型的旋转和乘法如下图所示。 有没有办法顺利实现我的目标?问题是我经常在其他应用程序中看到此操作而没有问题,因此必须达到我的目标。
谢谢!
PS:请不要被评论所激怒,他们只是试图找到另一种方式!"钢铁图像" https://drive.google.com/file/d/0B72QIg-baxzjakJsQkFRZFVFOFU/edit?usp=sharing
public void adjustColor(Bitmap bmp)
{
/*for(int i=0; i<bmp.getHeight()-1; i++) {
for(int j=0; j<bmp.getWidth()-1; j++) {
if(bmp.getPixel(j, i) != Color.TRANSPARENT) {
if(Color.green(bmp.getPixel(j, i)) <= 175 && Color.green(bmp.getPixel(j, i)) >= 65) {
red = Color.red(bmp.getPixel(j, i));
green = Color.green(bmp.getPixel(j, i));
blue = Color.blue(bmp.getPixel(j, i));
if (i == bmp.getHeight()-1) {
red = Color.red(bmp.getPixel(j, bmp.getHeight()));
green = Color.green(bmp.getPixel(j, bmp.getHeight()));
blue = Color.blue(bmp.getPixel(j, bmp.getHeight()));}
if ((red + mOfen.heatQ/10) <= 205) red = red + mOfen.heatQ/10;
bmp.setPixel(j, i, Color.rgb(red, green, blue));
}}
}
}*/
for(int h=0; h<bmp.getWidth()*bmp.getHeight(); h++) {
int x = h-bmp.getWidth()*(((int)h/bmp.getWidth()+1)-1);
int y = h/bmp.getWidth();
Log.d("roh", "y " + Integer.toString(y));
Log.d("roh", "height " + Integer.toString(bmp.getHeight()));
if(Color.green(bmp.getPixel(x, y)) <= 175 && Color.green(bmp.getPixel(x, y)) >= 65) {
bmp.setPixel(x, y, Color.WHITE);
red = Color.red( allpixels[h] );
green = Color.green( allpixels[h] );
blue = Color.blue( allpixels[h] );
/* for(int n=1; n<=10; n++) {
/*Log.d("roh", "left " + Float.toString(mOfen.rRoh[n-1].left));
Log.d("roh", "right " + Float.toString(mOfen.rRoh[n-1].right));
Log.d("roh", "n " + Integer.toString(n));
Log.d("roh", "x+RohX " + Float.toString(x+RohX));
Log.d("roh", "top " + Float.toString(mOfen.rRoh[n-1].top));
Log.d("roh", "bottom " + Float.toString(mOfen.rRoh[n-1].bottom));
Log.d("roh", "n " + Integer.toString(n));
Log.d("roh", "y+RohY " + Float.toString(y+RohY)); */
/* if( mOfen.rRoh[n-1].left < x+RohX && y+RohY > mOfen.rRoh[n-1].top &&
mOfen.rRoh[n-1].right > x+RohX && y+RohY < mOfen.rRoh[n-1].bottom) {
/*if ((mOfen.heat[n-1]) <= 245 && (mOfen.heat[n-1]) > red ) red = mOfen.heat[n-1]; */ if(red<255) red++;
/* Log.d("red", "red" + Integer.toString(red));
Log.d("red", Float.toString(x+mOfen.rRoh[n-1].left));
Log.d("red", Float.toString((mOfen.rRoh[n-1].left)));
}} */
allpixels[h] = Color.rgb(red, green, blue);
}
}
copyArrayIntoBitmap(bmp);
//bmp.setPixels(allpixels, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight());
}
public void copyBitmapIntoArray(Bitmap bmp)
{
allpixels = new int[bmp.getWidth()*bmp.getHeight()];
int count = 0;
for(int i=0; i<bmp.getHeight()-1; i++) {
for(int j=0; j<bmp.getWidth()-1; j++) {
allpixels[count] = bmp.getPixel(j, i);
count++;
}
}
}
public void copyArrayIntoBitmap(Bitmap bmp)
{
int count = 0;
for(int i=0; i<bmp.getHeight()-1; i++) {
for(int j=0; j<bmp.getWidth()-1; j++) {
bmp.setPixel(j, i, allpixels[count]);
count++;
}
}
}
答案 0 :(得分:1)
所以你的代码和你的问题有不同的操作。看起来你做的不仅仅是全局更新所有像素更红一点。我之所以这么说是因为你的问题中的两个代码(注释和未注释)都有一个条件部分,用于确定制作像素的红色程度。我还假设这就是简单的LightingColorFilter
不起作用的原因,因为您需要选择受影响的像素。
我立即发现了一些问题:
我打赌你在这段代码中遇到了很多关于内存分配和内存复制的I / O问题。显然,WxH是你的像素数。但这也是一个相当大的进行操作的人。因此,您对getPixel()
和setPixel()
的调用已经非常缓慢,并且对每个像素执行此操作都是不切实际的。如果您打算这样做,则应使用批量getPixels()
和setPixels()
。只有这一点才能加快你的大部分进程。
现在,如果你想要一个前向兼容的性能提升(比如可以通过更好的硬件更好地扩展),你可以查看RenderScript
这允许你在每个像素级别上工作,但跨多个CPU和GPU 。它有点像图像缓冲区的map-reduce框架。你将不得不写一些C,但如果你发现这个组件被大量使用,那么这可能会有所帮助,并且非常活泼(特别是对于较大的图像)。
答案 1 :(得分:0)
尝试使用LightingColorFilter,这里有一些例子: LightingColorFilter example或how to use the LightingColorFilter to make the image form dark to light