j2me中对图像的像素级处理

来源:互联网 发布:安装软件用什么软件源 编辑:程序博客网 时间:2024/05/22 05:33
 

作者:刘军

一、半透明效果
                                                                                                                
        MIDP2.0中提供了对图片的象素级的处理,利用这一点,我们可以对图片进行相关的处理,比如半透明,把彩色图片处理成灰度图片,以及图片变色效果都可以在J2ME里很方便地实现。

在进行这些操作之前,我们必须先了解JAVA中的一些位操作符:

<< >>   &   |

主要是这几个操作符,下面我们就开始我们的操作

       在
PNG里每个象素是一个ARBG格式,是一个8位的十六进制的数字,比如0xff121212,这个东西描述了图片的一个象素,我们可以通过Image类中的:

      getRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height)
方法获得一个rgbData,这个rgbData就保存了图片所对应的象素信息
,取出象素信息之后我们需要对其进行透明效果的处理,透明效果的值是保存在8位中的最高2位,你可以把这个象素值转换成16进制输出,一般情况下最高2位应该都是为FF,也就是不透明,我们现在需要把这个FF改成一个比他小的值,那么我们的图片就透明了,最高位为00的时候图片就全透明了

      其实816进制对应了32位的2进制,那么我们可以通过下面的方法取出他的最高2

          a = argb>>24//把这个数向右移动24位,那么剩下的8位就是我们要的最高位了

修改之后我们再通过下面的方法可以把他存回去

        Argb = a<<24 |( argb & 0x00FFFFFF);

     那么我们通过循环把这个图片的所有象素信息都改变之后,再用改变的象素信息来构造一个图片,或者这个通过我们的Graphics下面的drawRGB方法直接画出来的就是一个半透明效果的图片了,你可以在画这个图片之前先画一个其他的图片,这样你就可以很明显地看到效果了。


import java.io.IOException;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;


/**
* @author 刘军
* @version 1.0
*/
public class TCanvas extends Canvas {
Image image;//要处理的图片
int argb[];
public TCanvas() {
   super();
   try {
    image = Image.createImage("/test.png");//导入图片
   } catch (IOException e) {
    e.printStackTrace();
   }
   argb = new int[image.getWidth()*image.getHeight()];
   image.getRGB(argb,0,image.getWidth(),0,0,image.getWidth(),image.getHeight());//获得图片的ARGB值
   int temp;
   int a= 100;//把象素的透明度都设置为100
   for(int i=0;i<argb.length;i++)
   {
    argb[i]=(a<<24) | (argb[i] & 0x00FFFFFF);// 修改最高2位的值
   }
}

protected void paint(Graphics g) {
   g.drawImage(image,0,0,Graphics.TOP|Graphics.LEFT);
   g.drawRGB(argb,0,image.getWidth(),0,100,image.getWidth(),image.getHeight(),true);// 画象素数组
}

}

二、透明到不透明效果

上面我们说到了怎么把一个图片处理成一个半透明的效果,下面是一个图片从透明到不透明的的变化效果

import java.io.IOException;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

public class TCanvas extends Canvas implements Runnable{
   Image image;//要处理的图片
   int argb[];
   int a= 0;//把象素的透明度初始值设置为0,然后在线程中不断地增加这个值

public TCanvas() {
   super();
   try {
    image = Image.createImage("/test.png");//导入图片
   } catch (IOException e) {
    e.printStackTrace();
   }
   argb = new int[image.getWidth()*image.getHeight()];
   image.getRGB(argb,0,image.getWidth(),0,0,image.getWidth(),image.getHeight());//获得图片的ARGB值
   int temp;
  
   for(int i=0;i<argb.length;i++)
   {
    argb[i]=(a<<24) | (argb[i] & 0x00FFFFFF);// 修改最高2位的值
   }
   Thread t = new Thread(this);
   t.start();
}

protected void paint(Graphics g) {
   g.setColor(0xffffff);
   g.fillRect(0,0,getWidth(),getHeight());
   g.setColor(0);
   g.drawImage(image,0,0,Graphics.TOP|Graphics.LEFT);
   g.drawRGB(argb,0,image.getWidth(),0,100,image.getWidth(),image.getHeight(),true);// 画象素数组
   g.drawString(a+"",10,90,Graphics.TOP|Graphics.LEFT);
}

public void run()
{
   while(a<256)
   {
    //改变象素内容
    for(int i=0;i<argb.length;i++)
    {
     argb[i]=(a<<24) | (argb[i] & 0x00FFFFFF);// 修改最高2位的值
    }
    repaint();//重绘屏幕
    a++;
    try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
}
}

三、灰度效果

      在我们的游戏里面经常会需要把当前的场景绘制成一个灰度的场景,比如说当角色死亡的时候没,我们会把场景弄成一个灰色,那么怎么实现一个灰色的场景呢,一个办法就是做一个灰色的图片,把他画上去,但是这样会占用我们JAR文件的大小,那么我们现在来了解一下怎么把一个彩色的图片绘制成一个灰色的图片。

      我们的灰度图片和彩色图片一样,也是由RGB三原色组成的,但是灰度图片有一个特点,那就是他的RGB3个值是相等的,但是我们的彩色图片RGB3个值之间没有特别的关系,所以我们要做的就是把彩色图片中RGB3个值改成一个相等的值,改成一个什么样的值呢,我们只要求出彩色图片的RGB3个值的平均值,然后把RGB都改成这个平均值就好了。

先取出RGB3个值

    r = (argb[i] & 0x00FF0000)>>16;//获得red

   g = (argb[i] & 0x0000ff00)>>8;//获得green

   b = argb[i] & 0x000000ff;//获得blue

然后求r,g,b的平均值

temp = (r+g+b)/3;

再合并出新的象素值:

r = temp<<16;

g = temp<<8;

b = temp;

argb[i] = 0xff000000 | r | g | b;//合并3个色彩

最后把修改后的这个RGB数组绘制出来就ok

 

import java.io.IOException;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;



public class TCanvas extends Canvas{
Image image;//要处理的图片
int argb[];

public TCanvas() {
   super();
   try {
    image = Image.createImage("/test.png");//导入图片
   } catch (IOException e) {
    e.printStackTrace();
   }
   argb = new int[image.getWidth()*image.getHeight()];
   image.getRGB(argb,0,image.getWidth(),0,0,image.getWidth(),image.getHeight());//获得图片的ARGB值
   int temp;
   int r,g,b;
  
   for(int i=0;i<argb.length;i++)
   {
    r = (argb[i] & 0x00FF0000)>>16;//获得red值
    g = (argb[i] & 0x0000ff00)>>8;//获得green值
    b = argb[i] & 0x000000ff;//获得blue值
    temp = (r+g+b)/3;//求他们的平均值,并把r,g,b的值都等于这个值,当RGB三个值相等的时候这个象素的色彩就是灰度的了
    r = temp<<16;
    g = temp<<8;
    b = temp;
    argb[i] = 0xff000000 | r | g | b;//合并3个色彩
   }
}

protected void paint(Graphics g) {
   g.setColor(0xffffff);
   g.fillRect(0,0,getWidth(),getHeight());
   g.setColor(0);
   g.drawImage(image,0,0,Graphics.TOP|Graphics.LEFT);
   g.drawRGB(argb,0,image.getWidth(),0,100,image.getWidth(),image.getHeight(),true);// 画象素数组
  
}
}

四、颜色变换
     在我们游戏编程中经常会碰到一些图片,只是颜色不同,其他的都相同,我们在MIDP1.0里面需要做几张这样的图片,那么势必会增加我们JAR文件的大小,在MIDP2.0里面我们有了办法,可以通过一张图片变出N张不同颜色的图片出来。

      在前面我们已经了解了,怎么样得到一个图片的象素,其实改变图片的颜色也可以通过改变象素的值来实现,首先我们要获得相应的象素的R,G,B的值,这个方法在我们处理灰度图片的时候已经了解了:

   r = (rgb[j]& 0x00ff0000)>>16;
    g = (rgb[j]& 0x0000ff00)>>8;
    b = rgb[j]& 0x000000ff;

得到这些方法之后我们可以把他们进行对换,这样的话就可以得到不同颜色的图片了,当然,你可以进行跟复杂的一些变化

   temp = r;
    r = b;
    b = g;
    g = temp;

下面我给出这个程序的完整代码:

import java.io.IOException;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

public class GCanvas extends Canvas{
   Image i;
    int rgb[] = new int[86*50];

public GCanvas() {
   super();
   try {
    i = Image.createImage("/h.png");
   } catch (IOException e) {
    e.printStackTrace();
   }
   i.getRGB(rgb,0,i.getWidth(),0,0,i.getWidth(),i.getHeight());
   int r,g,b,temp;
   for(int j=0;j<rgb.length;j++)
   {
    r = (rgb[j]& 0x00ff0000)>>16;
    g = (rgb[j]& 0x0000ff00)>>8;
    b = rgb[j]& 0x000000ff;
    temp = r;
    r = b;
    b = g;
    g = temp;
    rgb[j] = ((r<<16) |(g<<8)| b) | 0xff000000;
   }
}
public void paint(Graphics g)
{
   g.drawImage(i,0,0,0);
   g.drawRGB(rgb,0,i.getWidth(),0,60,i.getWidth(),i.getHeight(),true);
}
}

最后得到的效果如下:

 

 

原创粉丝点击