Pergunta

existe alguma possibilidade em J2ME para converter uma imagem (carregado a partir de um ficheiro png com alpha) para um novo transparentes imagem em tons de cinza?

Até agora eu só tenho os valores rgb, mas não o alpha.

Obrigado.

Editar:sim, deve ser de 32 bits em tons de cinza.

Foi útil?

Solução

Eu encontrei a solução e aqui está o código:

    public Image getGrayScaleImage() {
    int[] rgbData = new int[getWidth() * getHeight()];
    image.getRGB(rgbData, 0, getWidth(), 0, 0, getWidth(), getHeight());
    for (int x = 0; x < getWidth() * getHeight(); x++) {
        rgbData[x] = getGrayScale(rgbData[x]);
    }
    Image grayImage = Image.createRGBImage(rgbData, getWidth(), getHeight(), true);
    return grayImage;
}

private int getGrayScale(int c) {
    int[] p = new int[4];
    p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level
    p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level
    p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level
    p[3] = (int) (c & 0x000000FF); // Blue level

    int nc = p[1] / 3 + p[2] / 3 + p[3] / 3;
    // a little bit brighter
    nc = nc / 2 + 127;

    p[1] = nc;
    p[2] = nc;
    p[3] = nc;

    int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
    return gc;
}

O GetRGB retorna o valor de cor que também inclui o canal alfa. Então, eu só tive que alterar cada valor na matriz e criar uma imagem a partir disso.

Encontrei um documento útil no fórum da Nokia: MIDP 2.0: Trabalhando com pixels e drawrgb ()

Outras dicas

Obrigado por o código na conversão para tons de cinza.Percebi, no entanto, que, no Nokia Series 40 dispositivos, esse código é executado muito lentamente.

Há 2 otimizações .O principal é remover qualquer objeto de criação, em getGrayScale().Atualmente , um objeto de matriz é criada para cada pixel .Para uma média de ,digamos, QVGA, mostrar que é 76800 matriz de objetos criados, o que é um monte de lixo, e provavelmente vai se chamar GC.Definir o int[4] como um campo na classe remove o objeto de criação.O trade-off aqui está uma pequena quantidade de memória RAM utilizada para a classe.

O segundo é colocar a largura e altura em getGrayScaleImage().Em alguns dispositivos, as chamadas de método para getWidth() e getHeight() será chamado repetidamente sem otimizações ( um compilador JIT vai ser OK, mas alguns dispositivos interpretados não ).Então , novamente para QVGA, o getWidth() e getHeight() será chamado a alguns >150000 entre eles.

Em todos, eu achei essa versão modificada corria muito mais rápido :-)

public Image getGrayScaleImage(Image screenshot) {
    int width = getWidth();
    int height = getHeight();
    int screenSizeInPixels = (width * height);

    int[] rgbData = new int[width * height];

    image.getRGB(rgbData, 0, width, 0, 0, width, height);
    for (int x = 0; x < screenSizeInPixels ; x++) {
        rgbData[x] = getGrayScale(rgbData[x]);
    }

    Image grayImage = Image.createRGBImage(rgbData, width, height, true);
    return grayImage;
}

static int[] p = new int[4];
private int getGrayScale(int c) {

    p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level
    p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level
    p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level
    p[3] = (int) (c & 0x000000FF); // Blue level

    int nc = p[1] / 3 + p[2] / 3 + p[3] / 3;
    // a little bit brighter
    nc = nc / 2 + 127;

    p[1] = nc;
    p[2] = nc;
    p[3] = nc;

    int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
    return gc;
}

( Se você realmente não quiser usar a classe de espaço de dados, basta substituir o int[] com quatro diferentes locais variáveis int que gostaria de viver na pilha)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top