`
lukew
  • 浏览: 51647 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

修改png图的调色板

阅读更多
今天在硬盘上挖出这个存放了几年的代码。又回忆起3年前的那个j2me手机游戏程序员……

这个算法是参考一位高人的文章,直接读取并修改png格式图片的调色板,然后生成新的调色板替代原来的。
这样可以实现游戏中常见的变色效果,可以解决游戏容量有限,不能存放太多精灵图片的问题。

具体过程其实并不复杂,大家可以先搜索资料,先看看png图片的格式定义。这个算法正是找到调色板区,根据原有格式修改之后,生成新的crc校验码,然后替换原来的调色板。这样就可以用一个png图片,创建多个变色副本。
<!---->public class PalettedImage {
 
    
public Image getPalettedImage(byte[] data, int[] originalColors,
            
int[] palettedColors) {
        
byte[] tempData = new byte[data.length];
        System.arraycopy(data, 
0, tempData, 0, data.length);
        Image img 
= null;
        
int[] parameter = { 000 };
        analyze(tempData, parameter);
        
for (int i = 0; i < originalColors.length; i++) {
            replaceColor(tempData, parameter, originalColors[i],
                    palettedColors[i]);
        }
        fillData(tempData, parameter);
        
try {
            img 
= Image.createImage(tempData, 0, data.length);
        } 
catch (Exception e) {
            System.out.println(
"getPalettedImage  &&  " + e.toString());
        }
        
return img;
    }
 
    
private void analyze(byte[] data, int[] para) {
        
int offset = 8;
        
int chunkLen = 0;
        
while (data[offset + 4!= 0x50 || data[offset + 5!= 0x4c
                
|| data[offset + 6!= 0x54 || data[offset + 7!= 0x45) {
            chunkLen 
= readInt(data, offset);
            offset 
+= (4 + 4 + chunkLen + 4);
        }
        chunkLen 
= readInt(data, offset);
        para[
2= chunkLen / 3;
        para[
0= offset + 8;
        para[
1= offset + 8 + chunkLen;
    }
 
    
private int readInt(byte[] data, int offset) {
        
return ((data[offset] & 0xFF<< 24)
                
| ((data[offset + 1& 0xFF<< 16)
                
| ((data[offset + 2& 0xFF<< 8| (data[offset + 3& 0xFF);
    }
 
    
private void replaceColor(byte[] data, int[] para, int oldColor,
            
int newColor) {
        
byte rr = (byte) ((oldColor >> 16& 0xff);
        
byte gg = (byte) ((oldColor >> 8& 0xff);
        
byte bb = (byte) (oldColor & 0xff);
        
for (int i = 0, offset = para[0], temp = 0; i < para[2]; i++, offset += 3) {
            
if (rr == data[offset] && gg == data[offset + 1]
                    
&& bb == data[offset + 2]) {
                data[offset] 
= (byte) ((newColor >> 16& 0xff);
                data[offset 
+ 1= (byte) ((newColor >> 8& 0xff);
                data[offset 
+ 2= (byte) (newColor & 0xff);
                
break;
            }
        }
    }
 
    
private void fillData(byte[] data, int[] para) {
        
int checksum = update_crc(data, para[0- 4, para[2* 3 + 4);
        data[para[
1]] = (byte) ((checksum >> 24& 0xff);
        data[para[
1+ 1= (byte) ((checksum >> 16& 0xff);
        data[para[
1+ 2= (byte) ((checksum >> 8& 0xff);
        data[para[
1+ 3= (byte) ((checksum) & 0xff);
    }
 
    
private int update_crc(byte[] buf, int off, int len) {
        
int c = 0xffffffff;
        
int n, k;
        
int xx;
        
int[] crc_table = new int[256];
        
for (n = 0; n < 256; n++) {
            xx 
= n;
            
for (k = 0; k < 8; k++) {
                
if ((xx & 1== 1) {
                    xx 
= 0xedb88320 ^ (xx >>> 1);
                } 
else {
                    xx 
= xx >>> 1;
                }
            }
            crc_table[n] 
= xx;
        }
 
        
for (n = off; n < len + off; n++) {
            c 
= crc_table[(c ^ buf[n]) & 0xff^ (c >>> 8);
        }
        
return (c ^ 0xffffffff);
    }
 
}


接口就是getPalettedImage()函数,只需要输入原始图片的byte数组,以及需要替换颜色的颜色值还有目标颜色值就行了。因为可以同时替换多个颜色,所以输入参数是代表颜色的整形的数组。总之,要保证原始颜色与目标颜色一一对应就好了。方法简单实用。

欢迎大家使用并留下宝贵的意见。当然,也可以修改一下这个函数,做一些特殊的效果。这里就不多说了。
不过这个代码用处已经不大,因为现在的手机基本上都支持midp2.0所以可以使用更方便的方法替换颜色。

总之,再次感谢这位已经被我忘掉名字的大侠,关键代码是他写的,我只是修改整理而已。
分享到:
评论

相关推荐

    jquery调色板插件

    5. **wheel.png, mask.png, marker.png**:这些都是图片资源文件,用于构建调色板的视觉元素。`wheel.png` 是颜色轮的图像,`mask.png` 可能是用来遮罩颜色轮的一部分,`marker.png` 则可能是用来标记当前选中的颜色...

    java 替换图片颜色 修改PNG图片颜色

    将图片加载到内存 循环图片每个像素 找到你需要修改的像素 进行颜色修改。然后再图片BASE64

    位图与调色板

    4. 调色板操作:如创建、修改、索引颜色以及应用新的调色板到位图。 5. 显示和渲染:将位图数据和调色板信息转化为屏幕上可见的图像。 在"代码中国.txt"和"代码中国.url"中,可能包含了更多关于编程和代码分享的...

    位图与调色板源代码bmp_in_mdiclient2.zip_BMP 调色板_C#调色_c# 调色板_in_调色板

    调色板(Palette)在位图中起到至关重要的作用,尤其是在8位或更低位深度的图像中。因为这些位深度无法表示丰富的颜色,所以需要调色板来映射每个像素的数值到实际的颜色。调色板是一个颜色表,包含了所有可能的颜色...

    位图调色板

    3. **编辑调色板**:在某些情况下,我们可能需要修改调色板,比如改变某些颜色或者减少颜色数以降低图像的色彩深度。这需要对调色板进行增删改操作,并确保更新后的调色板与像素数据同步。 4. **颜色空间转换**:...

    Png图片换色的方法

    该方法主要应用于索引类型的图片,即包含PLTE调色板的Png图片。通过修改调色板和使用CRC算法生成新的验证码,可以实现图片颜色的改变。 Png图片换色的方法的原理是基于Png图片的存储格式。Png图片主要由三部分组成...

    duilib 仿酷狗 QQ调色板修改版3

    `cursor.png`文件是一个光标图像,很可能用于指示用户当前在调色板上的位置。在设计用户界面时,这种定制的光标可以提高用户体验,因为它清晰地表明了用户与界面的交互点。 另外,`说明.txt`和`新调色板说明.txt`两...

    PNG转8位深度

    在PNG图像中,位深度决定了颜色调色板的大小。例如,一个8位的PNG图像可以有256种不同的颜色,因为2的8次方等于256。这适用于所有通道,包括红、绿、蓝(RGB)和可能存在的透明度通道(阿尔法通道)。当将高位深度的...

    位图与调色板bitmap_picture_demo

    3. **调色板管理**:创建、修改和应用调色板。了解如何根据需要动态调整调色板,以达到最佳的显示效果。 4. **图像显示**:将解析出的位图数据和调色板信息在屏幕上渲染出来。这可能涉及到图形库的使用,如OpenGL、...

    商业编程-源码-位图与调色板源代码 ebgfx_xray.zip

    3. **调色板管理**:源代码可能会有一个函数或类来创建、修改和查询调色板。这可能涉及颜色的添加、删除、索引操作以及颜色空间转换。 4. **图像渲染**:从位图数据和调色板生成屏幕上可见图像的过程是关键。这部分...

    商业编程-源码-位图与调色板源代码 pcxview_demo.zip

    位图与调色板在计算机图形学中是两个至关重要的概念,特别是在商业编程领域,它们在图像处理、游戏开发、用户界面设计等多个方面都有广泛应用。本文将深入探讨这两个概念,并结合"pcxview_demo"这个源码示例,来解析...

    商业编程-源码-位图与调色板源代码 enh_diblook.zip

    例如,一个图像查看器或者编辑器需要能够读取和解析位图文件格式,如BMP、PNG或JPEG,这些格式都涉及到位图和调色板的使用。 "enh_diblook.zip"中的源代码可能是一个增强的设备独立位图(DIB,Device Independent ...

    PNG图像数据结构详细介绍

    - 颜色类型:0-灰度,2-真彩色(RGB),3-索引颜色(调色板),4-灰度+Alpha,6-真彩色+Alpha。 - 位深度:1、2、4、8或16位,决定每个像素的颜色精度。 3. **压缩方法**: PNG使用ZIP算法进行无损压缩,通过对...

    PNG图像文件格式解析

    - **调色板数据块(PLTE)**:如果图像使用了调色板,则该数据块包含调色板的颜色条目。 - **图像数据块(IDAT)**:包含经过压缩的图像像素数据。 - **图像结束数据块(IEND)**:标志着PNG文件的结束。 ##### ...

    pngxpal:从索引的png图像中提取调色板。-开源

    在PNG图像中,调色板是用于存储颜色信息的数组,它定义了图像中每个像素可以使用的颜色。当一个PNG图像使用索引颜色模式时,每个像素不再直接存储RGB值,而是存储一个索引,这个索引对应调色板中的某个颜色。这样...

    商业编程-源码-位图与调色板源代码 bitmap_picture_demo.zip

    在这个“商业编程-源码-位图与调色板源代码 bitmap_picture_demo.zip”压缩包中,我们可以期待找到一些关于如何在编程中处理位图和调色板的示例代码。这些源代码可能涵盖以下几个方面: 1. **位图文件格式解析**:...

    PNG图片数据格式.PDF

    - **PLTE**:调色板数据块,仅用于索引颜色类型的图像,位于图像数据块IDAT之前。 - **IDAT**:图像数据块,包含压缩后的图像数据,可以出现多次。 - **IEND**:图像结束数据块,标记PNG文件的结束。 #### 辅助数据...

    隐写术11-索引图像及其调色板

    为了隐藏信息,可以在调色板的RGB值中添加或修改微小的位模式,这些位模式可以代表隐藏的数据。解码时,需要逆向操作,从这些微小的差异中提取出隐藏的信息。 在提供的压缩包文件中,"Steganography-11-Indexed-...

    CDib.rar_CDib_CDib类_调色板

    `CDib`类是对微软MFC(Microsoft Foundation Classes)库的扩展,它提供了方便的方法来处理DIB,如加载、保存、创建调色板、获取位图信息以及绘制位图等。 1. **CDib类概述** `CDib`是一个自定义类,它封装了与DIB...

    C#处理png图片位深度和交错属性

    在C#中,虽然.NET框架不直接提供修改PNG交错属性的API,但可以通过第三方库如libpng.NET或SharpPng等实现。这些库允许我们控制PNG的编码参数,包括是否启用Adam7交错。 综上所述,处理PNG图像的位深度和交错属性在...

Global site tag (gtag.js) - Google Analytics