Image对象转成PNG格式字节

Image对象转成PNG格式字节 。没有做LZ77压。

共三个文件。

pngtools.java image转png格式工具类

bytestools.java byte操作类

crcutil crc校验类

转载请注明出处,可自由使用,无使用限,但商用请通知我。

pngtools.java 


/** 
 * @功能:image 生成 png 字节
 * @作者: imuse
 * @MAIL: postzhu@hotmail.com
 * @blog: 
http://blog.csdn.net/imuse
 * @注 可自由使用,无使用限制。如商用请通知我
 
*/


import  javax.microedition.lcdui.Image;


public   class  PngTools  {
    
public static final int BIT4 = 4;
    
public static final int BIT8 = 8;
    
    
/** PNG tag. */
    
private static final byte PNG[] = {-11980787113102610};
    
    
/** IHDR tag. */
    
private static final byte IHDR[] = {73726882};
    
    
/** PLTE tag. */
    
private static final byte PLTE[]    =    {0x50,0x4C,0x54,0x45};
    
    
/** IDAT tag. */
    
private static final byte IDAT[] = {73686584};
    
    
/** LZ77 tag. */
    
private static final byte LZ77[] = {0x78, (byte)0xDA0x01};
    
    
/** IEND tag. */
    
private static final byte IEND[] = {(byte0x00, (byte0x00, (byte0x00, (byte0x00, (byte0x49, (byte0x45, (byte0x4E, (byte0x44, (byte0xAE, (byte0x42, (byte0x60, (byte0x82};
    
    
/** 
     * @功能 Image转成PNG字节
     * @参数 Image srcImage    原图<br>int bit色深<br>
     * @返回值 转换后的图片
     * 
*/


    
public static byte[] imageToPng(Image srcImg, int bit){
        
int srcW = srcImg.getWidth();
        
int srcH = srcImg.getHeight();
        
int[] srcRGB = new int[srcW];
        
        
int[] nColorArr = new int[0];
        
//取出图片中所用到的所有颜色
        for (int i = 0; i < srcH; i++{
            
//取一行颜色
            srcImg.getRGB(srcRGB, 0, srcW, 0, i, srcW, 1);
            
//取一行颜色中的不同值
            int[] temp = GetColorArr(srcRGB);
            
//将本行与上一次的结果连接
            int[] count = new int[nColorArr.length+temp.length];
            System.arraycopy(nColorArr, 
0, count, 0, nColorArr.length);
            System.arraycopy(temp, 
0, count, nColorArr.length, temp.length);
            
//取连接后的结果再次取不同颜色
            nColorArr = GetColorArr(count);
        }


        
//如果没找到颜色则返回空
        if(nColorArr.length==0){
            
return null;
        }

        
        
int nPosCRC = 0;
        
        
byte[] bRet;
        
//固定头
        bRet = BytesTools.appendBytes(null, PNG);
        
//固定头长度
        bRet = BytesTools.appendBytes(bRet, BytesTools.intToBytes(13));
        nPosCRC 
= bRet.length;
        
//IHDR
        bRet = BytesTools.appendBytes(bRet, IHDR);
        
//
        bRet = BytesTools.appendBytes(bRet, BytesTools.intToBytes(srcW));
        
//
        bRet = BytesTools.appendBytes(bRet, BytesTools.intToBytes(srcH));
        
//色深
        bRet = BytesTools.appendBytes(bRet, (byte)bit);
        
//颜色类型
        bRet = BytesTools.appendBytes(bRet, 0x03);
        
//规定此处总为0
        bRet = BytesTools.appendBytes(bRet, 0x00);
        
//同上
        bRet = BytesTools.appendBytes(bRet, 0x00);
        
//非隔行扫描
        bRet = BytesTools.appendBytes(bRet, 0x00);
        
//头信息CRC
        int nCRC = CRCUtil.checksum(bRet, nPosCRC, bRet.length-nPosCRC);
        bRet 
= BytesTools.appendBytes(bRet, BytesTools.intToBytes(nCRC));
        
//颜色总数
        int nColorLen = nColorArr.length;
        bRet 
= BytesTools.appendBytes(bRet, BytesTools.intToBytes(nColorLen*3));
        nPosCRC 
= bRet.length;
        
//PLTE
        bRet = BytesTools.appendBytes(bRet, PLTE);
        
for (int i = 0; i < nColorLen; i++{
            bRet 
= BytesTools.appendBytes(bRet, intToRGBBytes(nColorArr[i]));
        }

        
//CRC PLTE
        nCRC = CRCUtil.checksum(bRet, nPosCRC, bRet.length-nPosCRC);
        bRet 
= BytesTools.appendBytes(bRet, BytesTools.intToBytes(nCRC));
        
        
//IDTA长度
        int nIdtaLen = 0;
        
if(bit==BIT4){
            nIdtaLen 
= (srcW/2+1)*srcH;
        }
else if(bit==BIT8){
            nIdtaLen 
= (srcW+1)*srcH;
        }

        
int nLen = 4+LZ77.length+4+nIdtaLen;
        bRet 
= BytesTools.appendBytes(bRet, BytesTools.intToBytes(nLen));
        nPosCRC 
= bRet.length;
        
//IDAT
        bRet = BytesTools.appendBytes(bRet, IDAT);
        
//无压缩的LZ77压缩块
        bRet = BytesTools.appendBytes(bRet, LZ77);
        
//长度
        bRet = BytesTools.appendBytes(bRet, getIDATLen(nIdtaLen));
        
//数据区域
        int nAl = bRet.length;
        
if(bit==BIT4){
            bRet 
= BytesTools.appendBytes(bRet, getPngBytes(srcImg, nColorArr));
        }
else if(bit==BIT8){
            bRet 
= BytesTools.appendBytes(bRet, getPngBytes8(srcImg, nColorArr));
        }

        
//Adler32
        bRet = BytesTools.appendBytes(bRet, Adler(bRet, nAl, bRet.length-nAl));
        
//CRC
        nCRC = CRCUtil.checksum(bRet, nPosCRC, bRet.length-nPosCRC);
        bRet 
= BytesTools.appendBytes(bRet, BytesTools.intToBytes(nCRC));
        
//IEND
        bRet = BytesTools.appendBytes(bRet, IEND);
        
return bRet;
    }

    
    
//Adler校验
    private static byte[] Adler(byte[] bData, int nStart, int nLen){
        
int adler1=1;
        
int adler2=0;
        nLen 
+= nStart;
        
for(int i=nStart;i<nLen;i++)
        
{
            adler1
=adler1+((int)bData[i]&0xff);
            adler2
=adler1+adler2;
            adler1
%=65521;
            adler2
%=65521;
        }
      
        
int nRet = (adler2<<16| adler1 ;
        
return BytesTools.intToBytes(nRet);
    }

    
    
//8位色深IDAT数据
    private static byte[] getPngBytes8(Image srcImg, int[] nColorArr){
        
int srcW = srcImg.getWidth();
        
int srcH = srcImg.getHeight();
        
int[] srcRGB = new int[srcW];
        
        
byte[] bRet = new byte[(srcW+1)*srcH];
        
        
int nPos = 0;
        
for (int i = 0; i < srcH; i++{
            srcImg.getRGB(srcRGB, 
0, srcW, 0, i, srcW, 1);
            nPos 
= i;
            bRet[i
*srcW+nPos] = 0;
            
for (int j = 0; j < srcW; j++{
                bRet[i
*srcW+nPos+j+1= (byte)(getColorIndex(srcRGB[j], nColorArr)&0xFF);
            }

        }

        
return bRet;
    }

    
    
//4位色深IDAT数据
    private static byte[] getPngBytes(Image srcImg, int[] nColorArr){
        
int srcW = srcImg.getWidth();
        
int srcH = srcImg.getHeight();
        
int[] srcRGB = new int[srcW];
        
        
byte[] bRet = new byte[(srcW/2+1)*srcH];
        
        
int nPos = 0;
        
for (int i = 0; i < srcH; i++{
            srcImg.getRGB(srcRGB, 
0, srcW, 0, i, srcW, 1);
            nPos 
= i;
            bRet[i
*srcW/2+nPos] = 0;
            
int nIndex = 0;
            
for (int j = 0; j < srcW; j++{
                
if(j%2==1 && j!=0){
                    nIndex 
= nIndex | (getColorIndex(srcRGB[j], nColorArr)&0xFF);
                    bRet[i
*srcW/2+j/2+1+nPos] = (byte)nIndex;
                }
else{
                    nIndex 
= (getColorIndex(srcRGB[j], nColorArr)&0xFF)<<4;
                }

            }

        }

        
return bRet;
    }

    
    
//取颜色索引
    private static int getColorIndex(int nColor, int[] nColorArr){
        
int nLen = nColorArr.length;
        
int nIndex = -1;
        
for (int i = 0; i < nLen; i++{
            
if(nColor==nColorArr[i]){
                nIndex 
= i;
                
break;
            }

        }

        
return nIndex;
    }

    
    
//将一个int color转红绿蓝byte数组
    private static byte[] intToRGBBytes(int nColor){
        
byte[] bColor = new byte[3];
        
//
        bColor[0= (byte)(nColor>>16&0xFF);
        
//绿
        bColor[1= (byte)(nColor>>8&0xFF);
        
//
        bColor[2= (byte)(nColor&0xFF);
        
return bColor;
    }

    
    
//IDAT数据的长度,格式为:前两字节为IDAT长度,低字节在前,后两字节为前两字节的^值.
    private static byte[] getIDATLen(int nLen){
        
byte[] bRet = new byte[4];
        bRet[
0= (byte)(nLen & 0xFF);
        bRet[
1= (byte)(nLen >> 8 & 0xFF);
        bRet[
2= (byte)(bRet[0^ 0xFF);
        bRet[
3= (byte)(bRet[1^ 0xFF);
        
return bRet;
    }


    
//从一个int数据中取出不同的int值
    private static int[] GetColorArr(int[] nArr){
        
int nLen = nArr.length;
        
int nRet[] = new int[0];
        
for (int i = 0; i < nLen; i++{
            
int nrLen = nRet.length;
            
boolean is = true;
            
for (int j = 0; j < nrLen; j++{
                
if(nArr[i]==nRet[j]){
                    is 
= false;
                    
break;
                }

            }

            
if(is){
                
int[] temp = new int[nrLen+1];
                System.arraycopy(nRet, 
0, temp, 0, nrLen);
                temp[nrLen] 
= nArr[i];
                nRet 
= temp;
            }

        }

        
return nRet;
    }

}

 

bytestools.java


/** 
 * @功能:字节工具类
 * @作者: imuse
 * @MAIL: postzhu@hotmail.com
 * @blog: 
http://blog.csdn.net/imuse
 * @注 可自由使用,无使用限制。如商用请通知我
 
*/

public   class  BytesTools  {


    

    
/**
     * @功能: 将一个int值转为byte数组
     * @参数: int nNum 要转的int值
     * @返回值: byte[] bytesRet 转后的byte数组
     
*/

    
public static byte[] intToBytes(int nNum) {
        
byte[] bytesRet = new byte[4];
        bytesRet[
0= (byte) ((nNum >> 24& 0xFF);
        bytesRet[
1= (byte) ((nNum >> 16& 0xFF);
        bytesRet[
2= (byte) ((nNum >> 8& 0xFF);
        bytesRet[
3= (byte) (nNum & 0xFF);
        
return bytesRet;
    }


    
/**
     * @功能: 将一个长度为4 byte数组转为int
     * @参数: byte[] bNum要转的字节数组
     * @返回值: int retInt 转后的int值
     
*/

    
public static int bytesToInt(byte[] bNum) {
        
return bytesToInt(bNum, 0);
    }

    
    
/**
     * @功能: 将一个长度为4 byte数组转为int
     * @参数: byte[] bNum要转的字节数组<br>int nStartPos起始位置
     * @返回值: int retInt 转后的int值
     
*/

    
public static int bytesToInt(byte[] bNum, int nStartPos) {
        
int retInt = 0;
        retInt 
= ((bNum[nStartPos++& 0xFF<< 24);
        retInt 
+= (bNum[nStartPos++& 0xFF<< 16;
        retInt 
+= (bNum[nStartPos++& 0xFF<< 8;
        retInt 
+= bNum[nStartPos] & 0xFF;
        
return retInt;
    }


    
/**
     * @功能: 将一个INT的转为byte数组后追加到指定数组后
     * @参数: byte[] bDes追加目标<br>int bSrc要追加的int
     * @返回值: byte[] 追加后的字节数组
     
*/

    
public static byte[] appendBytes(byte[] bDes, int bSrc) {
        
return appendBytes(bDes, new byte[]{(byte)bSrc});
    }

    
    
/**
     * @功能: 将一个byte 数组追加到指定数组后
     * @参数: byte[] bDes追加目标<br>byte[] bSrc要追加的字节数组
     * @返回值: byte[] 追加后的字节数组
     
*/

    
public static byte[] appendBytes(byte[] bDes, byte[] bSrc) {
        
byte[] ret = null;
        
if (bDes == null{
            ret 
= bSrc;
        }

        
if (bSrc == null{
            ret 
= bDes;
        }

        
if (bDes != null && bSrc != null{
            ret 
= new byte[bDes.length + bSrc.length];
            System.arraycopy(bDes, 
0, ret, 0, bDes.length);
            System.arraycopy(bSrc, 
0, ret, bDes.length, bSrc.length);
        }

        
return ret;
    }


    
/**
     * @功能: 截取指定byte 数组中的字节数组
     * @参数: byte[] bSrc原字节数组<br>int nStartPos原字节数组起始位置<br>int nLen截取长度
     * @返回值: byte[] 截取后的字节数组
     
*/

    
public static byte[] subBytes(byte[] bSrc, int nStartPos, int nLen) {
        
byte[] ret = null;
        
if (bSrc != null{
            ret 
= new byte[nLen];
            
if((nStartPos+nLen)<=bSrc.length){
                System.arraycopy(bSrc, nStartPos, ret, 
0, nLen);        
            }

        }

        
return ret;
    }

    
    
/**
     * @功能: 查找子字节数组在父字节数组中的位置
     * @参数: byte[] bSrc父字节数组<br>byte[] bSub子字节数组
     * @返回值: int 在父字节数组中的位置,如未找到则返回-1
     
*/

    
public static int findSubBytesPos(byte[] bSrc, byte[] bSub){
        
int ret = -1;
        
        
int nSubLen = bSub.length;
        
int nLen = bSrc.length-nSubLen;
        
        
boolean b=true;
        
for(int i=0; i<=nLen; i++){
            b 
= true;
            
for (int j = 0; j < nSubLen; j++{
                
if(bSrc[i+j]!=bSub[j]){
                    b 
= false;
                    
break;
                }

            }

            
if(b){
                ret 
= i;
                
break;
            }

        }

        
return ret;
    }

    
}

 

crcutil.java

 


/** 
 * @功能:CRC校验
 * @作者: imuse
 * @MAIL: postzhu@hotmail.com
 * @blog: 
http://blog.csdn.net/imuse
 * @注 可自由使用,无使用限制。如商用请通知我
 
*/

public   class  CRCUtil  {
    
private static int[] crc_table;
      
    
private static void make_crc_table() 
      
int c; 
      
int n, k; 
      crc_table 
= new int[256]; 
      
for (n = 0; n < 256; n++
          c 
= n; 
          
for (k = 0; k < 8; k++
            
if ((c & 1== 1
              c 
= 0xedb88320 ^ (c >>> 1); 
            
else 
              c 
= c >>> 1
          }
 
          crc_table[n] 
= c; 
      }
 
    }
 
  
    
private static int update_crc(byte[] buf, int nStart, int nLen) 
      
int c = 0xffffffff
      
int n; 
  
      
if (crc_table == null
          make_crc_table(); 
      }
 
      
for (n = nStart; n < nLen + nStart; n++
          c 
= crc_table[(c ^ buf[n]) & 0xff^ (c >>> 8); 
      }
 
      
return c; 
    }
 
  
    
/**
     * @功能:    生成CRC校验码
     * @参数:    byte[] buf数据区域<br>int nStart起始位置<br>int nLen计算长度<br>
     * @返回值:    int CRC校验码
     * 
*/

    
public static int checksum(byte[] buf, int nStart, int nLen) 
      
return update_crc(buf, nStart, nLen) ^ 0xffffffff
    }
 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值