快速更改位图的颜色

时间:2013-12-26 20:37:27

标签: android colors bitmap

我试图实现一个简单的动作,即改变普通位图的颜色。 不幸的是,出现了一些错误。在我的情况下,我想要一个灰色钢的位图变成更红的钢。因此,我编写了一些代码,它获取每个像素的颜色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++;
        }
    } 
} 

2 个答案:

答案 0 :(得分:1)

所以你的代码和你的问题有不同的操作。看起来你做的不仅仅是全局更新所有像素更红一点。我之所以这么说是因为你的问题中的两个代码(注释和未注释)都有一个条件部分,用于确定制作像素的红色程度。我还假设这就是简单的LightingColorFilter不起作用的原因,因为您需要选择受影响的像素。

我立即发现了一些问题:

我打赌你在这段代码中遇到了很多关于内存分配和内存复制的I / O问题。显然,WxH是你的像素数。但这也是一个相当大的进行操作的人。因此,您对getPixel()setPixel()的调用已经非常缓慢,并且对每个像素执行此操作都是不切实际的。如果您打算这样做,则应使用批量getPixels()setPixels()。只有这一点才能加快你的大部分进程。

现在,如果你想要一个前向兼容的性能提升(比如可以通过更好的硬件更好地扩展),你可以查看RenderScript这允许你在每个像素级别上工作,但跨多个CPU和GPU 。它有点像图像缓冲区的map-reduce框架。你将不得不写一些C,但如果你发现这个组件被大量使用,那么这可能会有所帮助,并且非常活泼(特别是对于较大的图像)。

答案 1 :(得分:0)