Пользовательский метод для изменения масштаба PNG теряет прозрачность - PullRequest
5 голосов
/ 08 июля 2010

Привет, ребята, я работаю над j2ME-игрой для мобильных телефонов с поддержкой Java. Я пытаюсь масштабировать прозрачный PNG с помощью следующего метода:

// method derived from a Snippet from http://snippets.dzone.com/posts/show/3257
// scales an image according to the ratios given as parameters

private Image rescaleImage(Image image, double XRatio, double YRatio)
{
    // the old height and width
    int sourceWidth = image.getWidth();
    int sourceHeight = image.getHeight();

    // what the new height and width should be
    int newWidth = (int)(XRatio * sourceWidth);
    int newHeight = (int)(YRatio * sourceHeight);

    Image newImage = Image.createImage(newWidth, newHeight);
    Graphics g = newImage.getGraphics();

    for (int y = 0; y < newHeight; y++)
    {
        for (int x = 0; x < newWidth; x++)
        {
            g.setClip(x, y, 1, 1);
            int dx = (x * sourceWidth) / newWidth;
            int dy = (y * sourceHeight) / newHeight;
            g.drawImage(image, (x - dx), (y - dy), Graphics.LEFT | Graphics.TOP);
        }
    }
    return Image.createImage(newImage);
}

Он корректно масштабирует изображение, к сожалению, я, похоже, теряю прозрачность с изображением, возвращаемым методом. Я довольно новичок в этих понятиях, и любая помощь будет принята с благодарностью! Обратите внимание, что для правильного отображения на любом мобильном устройстве с поддержкой java необходимо изменить масштаб в коде, а не в каком-либо графическом редакторе.

Заранее спасибо!

Ответы [ 3 ]

4 голосов
/ 13 июля 2010

Спасибо всем, кто искал решения этой, казалось бы, широко распространенной и нерешенной проблемы. Мне удалось найти отличное решение на http://willperone.net/Code/codescaling.php

Вы просто меняете значение false в параметре createRGBImage на true. Это помечает метод для обработки старших бит каждого пикселя как альфа-значения. Вот моя реализация, не сильно отличается от оригинальной ссылки выше.

XRatio и YRatio объявляются как константы при инициализации холста, где XRatio = this.getWidth () (ширина экрана текущего телефона), разделенная на ширину исходного фонового изображения, а YRatio с getHeight () / высотой исходного фонового изображения .

// RESCALEIMAGE
// scales an image according to the ratios given as parameters
// derived from http://willperone.net/Code/codescaling.php

public static Image rescaleImage(Image original, double XRatio, double YRatio)
{
    // the original width and height
    int originalWidth = original.getWidth();
    int originalHeight = original.getHeight();

    // the target width and height
    int newWidth = (int)(XRatio * originalWidth);
    int newHeight = (int)(YRatio * originalHeight);

    // create and fill the pixel array from the original image
    int[] rawInput = new int[originalHeight * originalWidth];
    original.getRGB(rawInput, 0, originalWidth, 0, 0, originalWidth, originalHeight);

    // pixel array for the target image
    int[] rawOutput = new int[newWidth*newHeight];

    // YD compensates for the x loop by subtracting the width back out
    int YD = (originalHeight / newHeight) * originalWidth - originalWidth;
    int YR = originalHeight % newHeight;
    int XD = originalWidth / newWidth;
    int XR = originalWidth % newWidth;
    int outOffset= 0;
    int inOffset=  0;

    for (int y = newHeight, YE = 0; y > 0; y--)
    {
        for (int x = newWidth, XE = 0; x > 0; x--)
        {
            rawOutput[outOffset++] = rawInput[inOffset];

            inOffset += XD;
            XE += XR;

            if (XE >= newWidth)
            {
                XE -= newWidth;
                inOffset++;
            }
        }

        inOffset += YD;
        YE += YR;

        if (YE >= newHeight)
        {
            YE -= newHeight;
            inOffset += originalWidth;
        }
    }
    return Image.createRGBImage(rawOutput, newWidth, newHeight, true);
}
1 голос
/ 08 июля 2010

Возможно, потому что вы не различаете альфа в значениях пикселей.Что вы можете сделать, так это добавить дополнительную подпрограмму для обработки тех, у которых есть альфа, чтобы они сохранили свои возможные значения альфа.

По сути, он проверяет каждый пиксель, проверяет, есть ли у него альфа, если есть, проверяет, будет лина измененном изображении, если так, примените его там с его альфой, если нет, откажитесь от него.

0 голосов
/ 08 июля 2010

Может быть, метод класса Image ':

Image   getScaledInstance(int width, int height, int hints) 

хорошо подходит для того, что вам нужно ..?

От: http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/awt/Image.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...