重新缩放 PNG 的自定义方法失去透明度

发布于 2024-09-08 17:56:48 字数 1181 浏览 7 评论 0原文

大家好,我正在为支持 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 的移动设备上正确显示,重新缩放需要在代码中完成,而不是在任何类型的图像编辑器中完成。

提前致谢!

Hey folks, I am working on a j2ME game for java-capable cell phones. I am attempting to scale a transparent PNG with the following method:

// 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);
}

It scales the image correctly, unfortunately I seem to be losing the transparency with the image returned by the method. I am fairly new to these concepts, and any help would be greatly appreciated! Please note that in order to be properly displayed on any java-capable mobile device, the rescaling needs to be done in code, not in any sort of image editor.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

む无字情书 2024-09-15 17:56:49

感谢所有一直在为这个看似广泛存在且尚未解决的问题寻找解决方案的人。我设法在 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);
}

Thanks to everyone who has been looking for solutions to this seemingly wide-spread and unsolved problem. I managed to find a great solution at http://willperone.net/Code/codescaling.php

You just change the "false" in the createRGBImage parameter to a true. This flags the method to process the high-order bits of each pixel as alpha values. Here is my implementation, not much change from the original link above.

XRatio and YRatio are declared as constants when the canvas is initialized, where XRatio = this.getWidth() (the current phone's screen width) divided by your original background image width, and YRatio with getHeight() / original background image height.

// 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);
}
本王不退位尔等都是臣 2024-09-15 17:56:49

这可能是因为您没有区分像素值中的 alpha。您可以做的是添加一个额外的例程来处理带有 alpha 的例程,以便它们保留可能的 alpha 值。

基本上它会检查每个像素,看看它是否有 alpha,如果有,检查它是否会出现在调整大小的图像上,如果是,则将其与 alpha 一起应用到那里,如果没有,则丢弃它。

It is possibly because you don't distinguish alpha in the pixel values. What you can do is add an extra routine to handle the ones with alpha so they keep their possible alpha values.

Basically it's checking every pixel, see if it has alpha, if it has, check if it will be on the resized image, if so, apply it there with it's alpha, if not, discard it.

桃酥萝莉 2024-09-15 17:56:49

也许 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

Maybe the Image class' method:

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

is a good fit for what you need..?

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文