Переворачивание изображения

#java #image #graphics #transform #flip

#java #изображение #графика #преобразование #переворачивать

Вопрос:

Я создаю плиточную игру, в которой мне нужно переворачивать изображения. В имеющемся у меня коде это приводит к такой ошибке:

 Exception in thread "main" java.lang.IllegalArgumentException: Width (-1) and height (-1) cannot be <= 0
  

из этой строки:

 Image newImage = gc.createCompatibleImage(
        image.getWidth(null),
        image.getHeight(null),
        Transparency.BITMASK);
  

вот кодировка, которая у меня есть:

 public Image getMirrorImage(Image image) {
    return getScaledImage(image, -1, 1);
}

private Image getScaledImage(Image image, float x, float y) {
    // set up the transform
    AffineTransform transform = new AffineTransform();
    transform.scale(x, y);
    transform.translate(
        (x-1) * image.getWidth(null) / 2,
        (y-1) * image.getHeight(null) / 2);

    // create a transparent (not translucent) image
    Image newImage = gc.createCompatibleImage(
        image.getWidth(null),
        image.getHeight(null),
        Transparency.BITMASK);

    // draw the transformed image
    Graphics2D g = (Graphics2D)newImage.getGraphics();
    g.drawImage(image, transform, null);
    g.dispose();

    return newImage;
}
  

Кто-нибудь может объяснить мне, что мне может понадобиться сделать по-другому или как я могу заставить это работать? Большое спасибо

Комментарии:

1. Попробуйте умножить масштаб на -1 вместо того, чтобы устанавливать его равным -1.

2. Чтобы быстрее получить более качественную справку, опубликуйте SSCCE .

Ответ №1:

Для image.getWidth(null) и image.getHeight(null) возможно вернуть значение -1, если они еще не известны. Обработка изображений может выполняться одновременно, и она все еще может выполняться при попытке вызвать эти методы (даже локально это будет выполнять IIRC). Вот фрагмент кода, который я использовал раньше, чтобы дождаться загрузки изображения, прежде чем пытаться получить доступ к его ширине и высоте:

 private void waitForImage(Image image) {
    Container container = new Container();
    MediaTracker tracker = new MediaTracker(container);
    tracker.addImage(image, 0);
    try {
        tracker.waitForID(0, 1000);
    } catch (Exception e) {
    }
}
  

Я только что попробовал локальный тест, и время ожидания обычно составляло 1 мс для некоторых небольших изображений. На самом деле это не требует дополнительного времени, это просто заставляет ваш код ждать завершения последнего этапа, чтобы получить ширину и высоту.

Комментарии:

1. Либо это, либо используйте ImageIO.read(File/URL/InputStream) какие блоки до загрузки.

2. Спасибо за ваш пост, не могли бы вы привести пример того, как включить его в мою программу, чтобы я не получал ошибку?

3. @Andrew: о да, это верно, есть более современный способ сделать это. Мне напомнили о некотором масштабировании изображения, которое я выполнял десять лет назад в апплете, поэтому я почему-то сначала сослался на это 🙂

4. @mimis40 «не могли бы вы привести пример ..» Я рассмотрю это в тот самый момент, когда вы опубликуете SSCCE. Для изображения, не стесняйтесь использовать (много ссылок на) изображение, указанное на моей странице мультимедиа .

5. @mimis40: похоже, вам просто нужно вызвать waitForImage() код, который я опубликовал в начале вашего getScaledImage() метода.

Ответ №2:

Самый простой способ перевернуть изображение — это его отрицательное масштабирование. Пример:

 g2.drawImage(image, x, y, -width, height, null);
  

Это перевернет его по вертикали. Это перевернет его по горизонтали:

 g2.drawImage(image, x, y, width, -height, null);