【问题标题】:Change colour of a bitmap fastly快速改变位图的颜色
【发布时间】:2013-12-26 20:37:27
【问题描述】:

我试图实现一个实际上很简单的动作,即改变普通位图的颜色。 不幸的是,出现了一些错误。就我而言,我想要一张灰色钢的位图变成更红的钢。因此,我编写了一些代码,它获取每个像素的颜色 int 并提高每个像素的红色值。现在发生了两件事: 首先,转换所有像素确实需要很长时间,即使我使用 AsyncTask。 其次,当它完成一个循环时,整个位图会像下图一样旋转和倍增。 有什么方法可以顺利实现我的目标吗?问题是我经常在其他应用程序中看到此操作而没有问题,因此这一定是实现我的目标的一种方式。

谢谢!

PS:请不要被cmets激怒,他们只是想另辟蹊径!

“钢铁形象”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++;
        }
    } 
} 

【问题讨论】:

    标签: android colors bitmap


    【解决方案1】:

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

    我立即发现的一些问题:

    我敢打赌,关于这段代码中的所有内存分配和内存复制,您会遇到很多 I/O 问题。显然,WxH 是您的像素数。但这也是相当多的实体要对其进行操作。因此,您对getPixel()setPixel() 的迭代调用已经非常慢,并且为每个像素执行此操作是不切实际的。如果您打算这样做,您应该使用批量 getPixels()setPixels()。仅此一项就可以加快您的大部分流程。

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

    【讨论】:

    • 首先,感谢您的快速答复!正如您可能在我的代码 sn-p 中看到的那样,我已经尝试使用 setPixels() 而没有改进。你是对的,我知道,这种逐像素访问需要大量内存,但我不知道如何改进。但是我非常感谢您的新想法,唯一的问题是我对 C 的无知以及如何实现您的建议。因此,如果您能再次帮助我并且至少(如果您不介意)给我一些如何做到这一点的例子,那将是非常棒的。否则,我会尝试自己度过难关。 PS:平台是2.3.4! @GregGiacovelli
    【解决方案2】:

    尝试使用LightingColorFilter,这里有一些例子: LightingColorFilter examplehow to use the LightingColorFilter to make the image form dark to light

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多