Эй люди, я работаю над 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 мобильном устройстве, повторно масштабирующиеся потребности, которые будут сделаны в коде, не в любом виде редактора изображений.
Заранее спасибо!
Спасибо всем, кто искал решения этой, казалось бы, широко распространенной и нерешенной проблемы. Мне удалось найти отличное решение на 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);
}
Возможно, метод класса Image:
Image getScaledInstance(int width, int height, int hints)
подходит для того, что вам нужно...
From: http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/awt/Image.html
Возможно, потому, что вы не различаете альфа в значениях пикселей. Что вы можете сделать, так это добавить дополнительную процедуру для обработки тех, у которых есть альфа, чтобы они сохранили свои возможные альфа-значения.
В основном он проверяет каждый пиксель, проверяет, есть ли у него альфа, если есть, проверяет, будет ли он на изображении с измененным размером, если да, примените его туда с альфа, если нет, отбросьте.