在处理需要渲染精灵的Java应用程序时,我认为,不是将.png或.jpg文件加载为Image
或BufferedImage
,我可以加载byte[]
阵列包含调色板的索引(每个调色板16个颜色,因此每个byte
有两个像素),然后渲染该索引。使用调色板快速将字节渲染到画布
我现在有该方法从byte[]
阵列和彩色调色板生成BufferedImage
而初始化,考虑额外的时间来初始化但在这之后,它工作正常运行平稳,但也有只有4精灵在程序为止。我担心,如果有100多个精灵,将它们全部存储为BufferedImages
将对存储器造成太大的影响。这不仅意味着每个精灵1 BufferedImage
,而且实际上每个精灵/调色板组合的1个图像我都想使用。
这个函数创建的BufferedImage:
protected BufferedImage genImage(ColorPalette cp, int width, int height){ //Function to generate BufferedImage to render from the byte[]
BufferedImage ret = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); //Create the Image to return
for(int j=0; j<height; j++){ //Run a for loop for each pixel
for(int i=0; i<width; i++){
int index = (j * width + i)/2; //Get the index of the needed byte
int value = image[index] & 0x00ff; //Convert to "unsigned byte", or int
byte thing; //declare actual color index as byte
if(i % 2 == 0)thing = (byte)((value & 0b11110000) >>> 4); //If it's an even index(since it starts with 0, this includes the 1st one), get the first 4 bits of the value
else thing = (byte)(value & 0b00001111); //If it's odd, get the last four bits
ret.setRGB(i, j, cp.getColor(thing & 0x00ff).getRGB()); //Set the pixel in the image to the value in the Color Palette
}
}
return ret;
}
而这一次实际上它呈现在屏幕上:
public void render(Graphics g, int x, int y){ //Graphics to render to and x/y coords
g.drawImage(texture, x, y, TILE_WIDTH, TILE_HEIGHT, null); //Render it
}
我已经尝试了从byte[]
直接W/O呈现的另一种方法需要一个BufferedImage
,理论上这应该通过避免使用每个精灵的BufferedImage
来节省内存,但最终会非常缓慢。需要花费几秒钟的时间才能渲染每帧至多25个精灵来渲染屏幕!请注意0是一个Graphics
对象。
private void drawSquare(int x, int y, int scale, Color c){ //Draw each "pixel" to scale
if(g == null){ //If null, quit
return;
}
g.setColor(c); //Set the color
for(int i=x; i<x+scale; i++){ //Loop through each pixel
if(i<0)continue;
for(int j=y; j<y+scale; j++){
if(j<0)continue;
g.fillRect(x, y, scale, scale); //Fill the rect to make the "pixel"
}
}
}
public void drawBytes(byte[] image, int x, int y, int width, int height, int scale, ColorPalette palette){ //Draw a byte[] image with given byte[], x/y coords, width/height, scale, and color palette
if(image.length < width * height/2){ //If the image is too small, exit
return;
}
for(int j=0; j<height; j++){ //Loop through each pixel
for(int i=0; i<width; i++){
int index = (j * width + i)/2; //Get index
int value = image[index]; //get the byte
byte thing; //get the high or low value depending on even/odd
if(i % 2 == 0)thing = (byte)((value & 0b11110000) >>> 4);
else thing = (byte)(value & 0b00001111);
drawSquare((int)(x + scale * i), (int)(y + scale * j), scale, palette.getColor(thing)); //draw the pixel
}
}
}
那么,有没有使这些byte[]
阵列W/O需要BufferedImage
的更有效的方法?或者将数百个BufferdImage
加载到内存中真的没有问题?
编辑:我也试着做无BufferedImage的方法,但作为g
一个大的BufferedImage到一切都被渲染,然后呈现给Canvas
。主要区别在于g.fillRect(...
在该方法中更改为g.setRGB(...
,但它同样缓慢。
编辑:我正在处理的图像是16x16和32x32像素。
除了栅格数据(字节数组)之外,BufferedImage占用的内存很少。我怀疑你会发现这个优化有什么不同。 – VGR