Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的像素着色-需要更快的方法_Java_Image Processing_Colors - Fatal编程技术网

Java中的像素着色-需要更快的方法

Java中的像素着色-需要更快的方法,java,image-processing,colors,Java,Image Processing,Colors,我正在制作一个末日式的伪3D游戏。 世界被逐像素渲染成缓冲图像,随后显示在JPanel上。我想保持这种方法,这样照明单个像素会更容易 我想能够在游戏中的纹理颜色很多不同的颜色。 对整个纹理进行着色并将其存储在单独的缓冲图像中会占用我太多的时间和内存。因此,我在渲染阶段对纹理的每个像素着色 我遇到的问题是,为每个像素着色非常昂贵。当一堵不着色的墙覆盖整个屏幕时,我的速度约为65 fps。当彩色墙覆盖屏幕时,我的速度为30 fps 这是我的像素着色功能: //Change the color of

我正在制作一个末日式的伪3D游戏。 世界被逐像素渲染成缓冲图像,随后显示在JPanel上。我想保持这种方法,这样照明单个像素会更容易

我想能够在游戏中的纹理颜色很多不同的颜色。 对整个纹理进行着色并将其存储在单独的缓冲图像中会占用我太多的时间和内存。因此,我在渲染阶段对纹理的每个像素着色

我遇到的问题是,为每个像素着色非常昂贵。当一堵不着色的墙覆盖整个屏幕时,我的速度约为65 fps。当彩色墙覆盖屏幕时,我的速度为30 fps

这是我的像素着色功能:

//Change the color of the pixel using its brightness.
public static int tintABGRPixel(int pixelColor, Color tintColor) {
    //Calculate the luminance. The decimal values are pre-determined.
    double lum = ((pixelColor>>16 & 0xff) * 0.2126 +
                 (pixelColor>>8 & 0xff) * 0.7152 +
                 (pixelColor & 0xff) * 0.0722) / 255;

    //Calculate the new tinted color of the pixel and return it.
    return ((pixelColor>>24 & 0xff) << 24) |
           ((int)(tintColor.getBlue()*lum) & 0xff) |
           (((int)(tintColor.getGreen()*lum) & 0xff) << 8) |
           (((int)(tintColor.getRed()*lum) & 0xff) << 16);
}
//使用像素的亮度更改像素的颜色。
公共静态int-tintABGRPixel(int-pixelColor,Color-tintColor){
//计算亮度。十进制值是预先确定的。
双亮度=((像素颜色>>16和0xff)*0.2126+
(像素颜色>>8&0xff)*0.7152+
(像素颜色&0xff)*0.0722)/255;
//计算像素的新着色颜色并返回它。

返回((像素颜色>>24&0xff)在这一点上,你的计算非常接近金属。我认为你必须改变你的方法来真正改进事情,但一个快速的想法是缓存lum计算。这是像素颜色的一个简单函数,你的lum只依赖于此。如果你缓存它,它可以为你节省大量计算。而您正在缓存您也可以缓存此计算:

((pixelColor>>24 & 0xff) << 24)

((像素颜色>>24&0xff)在这一点上,你的计算非常接近金属。我认为你必须改变你的方法来真正改进事情,但一个快速的想法是缓存lum计算。这是像素颜色的一个简单函数,你的lum只依赖于此。如果你缓存它,它可以为你节省大量计算。而您正在缓存您也可以缓存此计算:

((pixelColor>>24 & 0xff) << 24)

((pixelColor>>24&0xff)为了获得更好的性能,您必须在图像处理过程中去除像
Color
这样的对象,如果您知道某个方法要调用一百万次(
image.width*image.height
次)然后最好内联这个方法。一般来说,JVM可能会内联这个方法本身,但您不应该冒险

您可以使用将所有像素放入一个数组

final int[] pixels = new int[width * height];
final PixelGrabber pixelgrabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, 0);

for(int i = 0; i < height; i++) {
    for(int j = 0; j < width; j++) {
        int p = pixels[i * width + j]; // same as image.getRGB(j, i);

        int alpha = ( ( p >> 24) & 0xff );
        int red = ( ( p >> 16) & 0xff );
        int green = ( ( p >> 8) & 0xff );
        int blue = ( p  & 0xff );

        //do something i.e. apply luminance
    }
}
final int[]像素=新int[宽度*高度];
最终PixelGrabber PixelGrabber=新的PixelGrabber(图像,0,0,宽度,高度,像素,0,0);
对于(int i=0;i>24)和0xff);
红色整数=((p>>16)和0xff);
绿色整数=((p>>8)和0xff);
蓝色整数=(p&0xff);
//做一些事情,例如应用亮度
}
}
上面只是一个如何迭代行和列索引的示例,但是在您的情况下不需要嵌套循环。这应该可以合理地提高性能

这可能也可以使用Java8流轻松地并行化,但是在处理图像时使用流之前要小心,因为流比普通的旧循环慢得多


在适用的情况下,您也可以尝试将
int
替换为
byte
(即单个颜色分量不需要存储在
int
)。基本上尝试使用基本数据类型,即使在基本数据类型中,也使用适用的最小值。

为了获得更好的性能,您必须在图像处理过程中去除像
颜色
这样的对象,如果您知道某个方法要调用一百万次(
image.width*image.height
次)然后最好内联这个方法。一般来说,JVM可能会内联这个方法本身,但您不应该冒险

您可以使用将所有像素放入一个数组

final int[] pixels = new int[width * height];
final PixelGrabber pixelgrabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, 0);

for(int i = 0; i < height; i++) {
    for(int j = 0; j < width; j++) {
        int p = pixels[i * width + j]; // same as image.getRGB(j, i);

        int alpha = ( ( p >> 24) & 0xff );
        int red = ( ( p >> 16) & 0xff );
        int green = ( ( p >> 8) & 0xff );
        int blue = ( p  & 0xff );

        //do something i.e. apply luminance
    }
}
final int[]像素=新int[宽度*高度];
最终PixelGrabber PixelGrabber=新的PixelGrabber(图像,0,0,宽度,高度,像素,0,0);
对于(int i=0;i>24)和0xff);
红色整数=((p>>16)和0xff);
绿色整数=((p>>8)和0xff);
蓝色整数=(p&0xff);
//做一些事情,例如应用亮度
}
}
上面只是一个如何迭代行和列索引的示例,但是在您的情况下不需要嵌套循环。这应该可以合理地提高性能

这可能也可以使用Java8流轻松地并行化,但是在处理图像时使用流之前要小心,因为流比普通的旧循环慢得多

在适用的情况下,您也可以尝试将
int
替换为
byte
(即单个颜色组件不需要存储在
int
)中。基本上可以尝试使用基本数据类型,甚至在基本数据类型中也可以使用适用的最小值。

并行执行此工作 线程不一定是并行化代码的唯一方法,CPU通常有指令集,比如SIMD,它允许您一次对多个数字计算同一个算术。GPU采用这种思想并使用它运行,允许您对数百到数千个数字并行运行同一个函数。我不知道在java中如何做到这一点,b但我相信,通过谷歌搜索,找到一种有效的方法是可能的

算法-减少工作量 是否有可能减少调用函数的时间量?每帧调用任何函数一百万次都会造成伤害。除非管理每个函数调用的开销(内联、重用堆栈帧、缓存结果)
int x = (pixelColor>>16 & 0xff), y = (pixelColor>>8 & 0xff), z = (pixelColor & 0xff);
int a = 2126, b = 7152, c = 722;
int top = a*x + b*y + c*z;
double temp = (double)(tintColor.getBlue() * top) / 10000 / 255;
int B = (int)temp & 0xff;
int x = (pixelColor>>16 & 0xff), y = (pixelColor>>8 & 0xff), z = (pixelColor & 0xff);
int a = 2126, b = 7152, c = 722;
int top = a*x + b*y + c*z);
int temp = (int)((double)(tintColor.getBlue()*top) / 2550000);
int B = temp & 0xff;
int x = (pixelColor>>16 & 0xff), y = (pixelColor>>8 & 0xff), z = (pixelColor & 0xff);
int a = 2126, b = 7152, c = 722;
int top = a*x + b*y + c*z;
int Btemp = (int)(( * top * 1766117501L) >> 52);
int B = temp & 0xff;
public static int tintABGRPixel(int pixelColor, Color tintColor) {
    //Calculate the luminance. The decimal values are pre-determined.
    int x = pixelColor>>16 & 0xff, y = pixelColor>>8 & 0xff, z = pixelColor & 0xff;
    int top = 2126*x + 7252*y + 722*z;
    int Btemp = (int)((tintColor.getBlue() * top * 1766117501L) >> 52);
    int Gtemp = (int)((tintColor.getGreen() * top * 1766117501L) >> 52);
    int Rtemp = (int)((tintColor.getRed() * top * 1766117501L) >> 52);

    //Calculate the new tinted color of the pixel and return it.
    return ((pixelColor>>24 & 0xff) << 24) | Btemp & 0xff | (Gtemp & 0xff) << 8 | (Rtemp & 0xff) << 16;
}