自定义PNG缩放方法丢失透明度

5

大家好,我正在为Java兼容的手机开发J2ME游戏。我尝试使用以下方法缩放透明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
感谢所有一直在寻找解决方案的人。我在以下网站找到了一个很好的解决方案:http://willperone.net/Code/codescaling.php 只需将createRGBImage参数中的“false”更改为“true”。这会将每个像素的高阶位处理为Alpha值。以下是我的实现,与上面的原始链接相比没有太多变化。
当初始化画布时,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

可能是因为您没有区分像素值中的alpha通道。您可以添加额外的程序来处理带有alpha通道的像素,以便它们保留其可能的alpha值。

基本上,它会检查每个像素,看看它是否具有alpha通道,如果有,则检查它是否将在调整大小后的图像上,如果是,则在那里应用它及其alpha值,如果不是,则丢弃它。


谢谢Yonathan。我正在尝试使用Image.GetRGB()和Image.createRGBImage()以及缩放算法来操作ARGB数组。祝我好运 :) - jbabey
ARGB方法的更新:它运行得非常好,除了缩放比率通常不是整数,这使得纯像素数组操作有点更加困难。 - jbabey

0

我认为这种方法在 J2ME 中不受支持,但还是谢谢你的回复。 - jbabey
我的错误,将发布另一个答案。 - Mike Tunnicliffe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接