Reflexão de imagens em Java ME

20 dezembro 2009
Este post mostra como criar um efeito de reflexão a partir de uma simples imagem.

Através do método createReflectedImage, da Classe que será mostrada abaixo, podemos fazer a reflexão da imagem passando 3 argumentos:

- A imagem original a ser refletida
- A cor de fundo (usado para imagens transparentes)
- A altura do efeito de reflexão


É necessário criar uma imagem mutável que irá realizar o efeito resultante:

int w = image.getWidth();

int h = image.getHeight();

Image reflectedImage = Image.createImage(w, h + reflectionHeight);

Foi armazenado a largura e altura da imagem original em 2 variáveis int, e em seguida, criou-se a imagem mutável com a mesma largura, mas com uma altura igual a h (imagem original) mais a altura da reflexão especificada.

Para fazer a cópia da imagem original é necessário usar o objeto Graphics da imagem mutável, preenchendo a imagem com a cor de fundo. Então é possível desenhar a imagem original na parte superior fazendo a mutação da imagem.

Para criar o efeito de reflexão em cada linha horizontal da parte da imagem refletida, toma-se a coordenada vertical correspondente da imagem original, então obtem-se os dados RGBA da linha horizontal correspondente à imagem original para calcular o alfa a ser aplicado a esta linha, e então aplicá-lo a cada elemento da matriz de dados RGB para elaborar os dados RGB da imagem refletida, utilizando seu objeto Graphics. Veja:

int[] rgba = new int[w];
int currentY = -1;

for(int i = 0; i < reflectionHeight; i++)
{
int y = (h - 1) - (i * h / reflectionHeight);

if(y != currentY)
image.getRGB(rgba, 0, w, 0, y, w, 1);

int alpha = 0xff - (i * 0xff / reflectionHeight);

for(int j = 0; j < w; j++)
{
int origAlpha = (rgba[j] >> 24);
int newAlpha = (alpha & origAlpha) * alpha / 0xff;

rgba[j] = (rgba[j] & 0x00ffffff);
rgba[j] = (rgba[j] | (newAlpha << 24));
}

g.drawRGB(rgba, 0, w, 0, h + i, w, 1, true);
}
Obs: O array rgba [] contém a linha atual dos dados de pixel, e será atualizada somente quando necessário. Desta forma a imagem é mutada no decorrer da coordenada y. Para usar o método basta criar a imagem original a ser refletida e chamar ReflectedImage.create(x, y, z), passando a imagem original como argumento, juntamente com a cor de fundo e a altura do efeito de reflexão. ReflectedImage.java
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

public class ReflectedImage
{
public static Image create(Image image, int bgColor, int reflectionHeight)
{
int w = image.getWidth();
int h = image.getHeight();

Image reflectedImage = Image.createImage(w, h + reflectionHeight);

Graphics g = reflectedImage.getGraphics();

g.setColor(bgColor);
g.fillRect(0, 0, w, h + reflectionHeight);

g.drawImage(image, 0, 0, Graphics.TOP | Graphics.LEFT);

int[] rgba = new int[w];
int currentY = -1;

for(int i = 0; i < reflectionHeight; i++)
{
int y = (h - 1) - (i * h / reflectionHeight);

if(y != currentY)
image.getRGB(rgba, 0, w, 0, y, w, 1);

int alpha = 0xff - (i * 0xff / reflectionHeight);

for(int j = 0; j < w; j++)
{
int origAlpha = (rgba[j] >> 24);
int newAlpha = (alpha & origAlpha) * alpha / 0xff;

rgba[j] = (rgba[j] & 0x00ffffff);
rgba[j] = (rgba[j] | (newAlpha << 24));
}

g.drawRGB(rgba, 0, w, 0, h + i, w, 1, true);
}
return reflectedImage;
}
}
MIDletReflexao.java
import java.io.IOException;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class MIDletReflexao extends MIDlet {

Display display;
private Form form;
private ImageItem imageItem;
private Image image;

public void startApp() {
display = Display.getDisplay(this);
display.setCurrent(getForm());
}

public Form getForm() {
if (form == null) {
form = new Form("Form", new Item[] { getImage() });
}
return form;
}

public ImageItem getImage() {
if (imageItem == null) {
try {
image = Image.createImage("/img.png");
} catch (IOException ex) {
ex.printStackTrace();
}
Image reflectedImage = ReflectedImage.create(image, 0xffffff, 64);
image=reflectedImage;
imageItem = new ImageItem("Reflexão", image, ImageItem.LAYOUT_DEFAULT, "Imagem perdida");
}
return (ImageItem) imageItem;
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}
}
Fonte: Classe Original: ReflectedImage.java http://wiki.forum.nokia.com/index.php

0 comentários:

Postar um comentário