Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как сделать операцию Zoom, для изображений 
:(
    Опции темы
Сириус
Дата 26.8.2006, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 26.11.2005

Репутация: нет
Всего: нет



Как сделать операцию Zoom для изображений. Такую как к примеру в программах ACDSee.
Моя основная проблема в том, что если взять к примеру маленькую картинку, то ее можно увеличить даже большее количество раз, нежели в ACDSee, а если брать картинку большую, то всего несколько раз и все. То есть гораздо меньше чем в ACDSee. Там количество возможных увеличений не меняется в зависимости от размера картинки. Вот в этом и состоит моя проблема, потаму что при увеличении картинки все равно  в конце КОНЦОВ программа прервется тупым OutOfMemoryError-ом, который уже изрядно надоел..как от этого избавится не знаю, ЛСД привел пример как поймать этот error, но все галимо, ничего не ловится. ВОобщем может вообще по иной технологии стоит делать операцию Zoom-а? прошу ваших советов!!
На всякий приведу код операции.


Код

 Image createZoomedImage(Image image)
  {


 try
{

 ReplicateScaleFilter rsFilter = new ReplicateScaleFilter(image.getWidth(null) * 2, image.getHeight(null) * 2);
    Toolkit can = Toolkit.getDefaultToolkit();
    image = can.createImage(new FilteredImageSource(image.getSource(), rsFilter));
    width = width * 2;
    height = height * 2;
    
}
catch(Exception ex)
{
  ex.printStackTrace();
}
catch(OutOfMemoryError err) //никак не ловит
{
  System.out.println("YES");
  System.err.println("catch " + err);
}

    return image;

  }


PM MAIL   Вверх
kkorsakoff
Дата 27.8.2006, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 378
Регистрация: 18.10.2005
Где: Санкт-Петербург

Репутация: 3
Всего: 14



OutOfMemoryError совсем не тупой, а вполне логичен, т.к. при каждом нажатии кнопки zoom ты увеличиваешь размер требуемой памяти в 4 раза. Причем что происходит со старой еще не понятно.

Надо алгоритм менять. Мне кажется надо в памяти хранить только одну копию картинки (на однократном увеличении). При нажатии zooma отрисовывать при помощи этого метода
Код

public abstract boolean drawImage(Image img,
                                  int dx1,
                                  int dy1,
                                  int dx2,
                                  int dy2,
                                  int sx1,
                                  int sy1,
                                  int sx2,
                                  int sy2,
                                  ImageObserver observer)


Тебе надо получить объект Graphics того компонента, на котором отрисовываешь, и вызвать drawImage с нужными параметрами. 

Сам не использовал, поэтому не знаю реальной скорости работы этого метода, а так же качества зума.
Только тогда надо продумать что с прокрутками, не будут ли тормоза. 
Для наибольшей эффективности конечно надо что-то с кэшированием и предварительной загрузкой делать.

Лично я полностью отказался  от scale-операций в java. ИМХО, абсолютно неприемлимо. Задачи были типа на сервере превратить около 200 фото примерно 2000x2000 в уменьшенные копии 50x50.

Теперь использую только ImageMagik. Справляется с задачей на отлично. Запускать либо через создание процесса либо через jni.

Это сообщение отредактировал(а) kkorsakoff - 27.8.2006, 11:43
PM MAIL WWW ICQ   Вверх
LSD
Дата 27.8.2006, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Проблема в том, что ресайз картинки происходит не сразу. Измени код:
Код
ReplicateScaleFilter rsFilter = new ReplicateScaleFilter(image.getWidth(null) * 2, image.getHeight(null) * 2);
Toolkit can = Toolkit.getDefaultToolkit();
image = can.createImage(new FilteredImageSource(image.getSource(), rsFilter));
width = width * 2;
height = height * 2;
image.getWidth(null);

и ты будешь ловить OutOfMemoryError. Только вот памяти это тебе не прибавит, учти что например JPEG файл 3000х2000 на диске занимает около 3Мб, а в памяти будет занимать 17.2МБ.


Цитата(kkorsakoff @  27.8.2006,  12:39 Найти цитируемый пост)
Сам не использовал, поэтому не знаю реальной скорости работы этого метода, а так же качества зума.
Только тогда надо продумать что с прокрутками, не будут ли тормоза. 
Для наибольшей эффективности конечно надо что-то с кэшированием и предварительной загрузкой делать.

Лично я полностью отказался  от scale-операций в java. ИМХО, абсолютно неприемлимо. Задачи были типа на сервере превратить около 200 фото примерно 2000x2000 в уменьшенные копии 50x50.

Ты наверно что то не правильно делал, скорее всего держал указатель на старое изображение.
Лично я писал програмку (даже где-то здесь выкладывал), которая строит превьюшки для файлов в каталоге. Так на каталог с 150 картинками 800х600 она затратила ~10Мб, включая GUI на Swing.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
kkorsakoff
Дата 27.8.2006, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 378
Регистрация: 18.10.2005
Где: Санкт-Петербург

Репутация: 3
Всего: 14



Ну то 800x600, а тут 2000x2000. В 8.333333333 раза больше однакоsmile Одновременно несколько пользователей могут запустить процесс уменьшения.
Ну да ладно память можно и увеличить, это уж от сервера зависит.
А скорость работы у тебя какая была? У меня уж очень низкая.

Да и вообще выделять такое количество памяти на тривиальнейшую задачу уменьшения картинок по моему мнению не очень адекватно.

Добавлю, что как яростный сторонник java, перешел на стороннюю программу не по своему желанию smile 
Потребовали пользователи сервиса, предоставив очевидные преемущества по скорости работы. Плюс было несколько вылетов OutOfMemory прямо во время полного отсутствия тех. админов.
Хотя это уже на вкус и цвет, давай лучше решать проблему Сириусаsmile
PM MAIL WWW ICQ   Вверх
Сириус
Дата 27.8.2006, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 26.11.2005

Репутация: нет
Всего: нет



kkorsakoff к сожалению ГРафиксом не выйдет, там куча новых проблем будет, а использовать что-то другое кроме Джавы нельзя..

LSD Вот не ловит

Exception in thread "Image Fetcher 3" java.lang.OutOfMemoryError: Java heap space

Код изменил 
Код

 Image createZoomedImage(Image image)
  {


     try
    {
    
        ReplicateScaleFilter rsFilter = new ReplicateScaleFilter(image.getWidth(null) * 2, image.getHeight(null) * 2);
        Toolkit can = Toolkit.getDefaultToolkit();
        image = can.createImage(new FilteredImageSource(image.getSource(), rsFilter));
        width = width * 2;
        height = height * 2;
        image.getWidth(null);
    
    }
    catch(Exception ex)
    {
      ex.printStackTrace();
    }
    catch(OutOfMemoryError err) //никак не ловит
    {
      System.out.println("YES");
      System.err.println("catch " + err);
    }
    
        return image;
    


  }



Но никак... smile 


PM MAIL   Вверх
LSD
Дата 28.8.2006, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Ну я уж не знаю как ты это делаешь.
Вот мой пример:
Код
import java.awt.*;
import java.awt.image.FilteredImageSource;
import java.awt.image.ReplicateScaleFilter;
import java.io.File;
import java.util.ArrayList;
import javax.imageio.ImageIO;

public class OutOfMemoryTest
{
  private static final String IMAGE_NAME = "Kolomenskoe.bmp";
  private static Runtime runtime = Runtime.getRuntime();
  private static Toolkit toolkit = Toolkit.getDefaultToolkit();

  public static void main(String[] args)
  {
    try
    {
      ArrayList<Image> list = new ArrayList<Image>();
      for(int i = 1; i <= 1000; i++)
      {
        System.out.printf("Iteration %1$d%n", i);
        printMem();
        Image image = ImageIO.read(new File(IMAGE_NAME));
        list.add(createZoomedImage(image));
        printMem();
      }
      System.out.printf("Processed %1$d images%n", list.size());
    }
    catch(Exception ex)
    {
      ex.printStackTrace();
    }
    catch(OutOfMemoryError err)
    {
      System.err.println(err + " | catched in main()");
    }
  }

  private static Image createZoomedImage(Image image)
  {
    try
    {
      ReplicateScaleFilter rsFilter = new ReplicateScaleFilter(image.getWidth(null) * 2, image.getHeight(null) * 2);
      image = toolkit.createImage(new FilteredImageSource(image.getSource(), rsFilter));
      image.getWidth(null);
    }
    catch(Exception ex)
    {
      ex.printStackTrace();
    }
    catch(OutOfMemoryError err)
    {
      System.err.println(err + " | catched in createZoomedImage()");
    }
    return image;
  }

  private static void printMem()
  {
    System.out.printf("Total memory: %1$,10d, used memory: %2$,14d%n", runtime.totalMemory(), runtime.totalMemory() - runtime.freeMemory());
  }
}

картинка 1280x1024 24BPP.
В консоли получаю следующее:
Цитата
Iteration 1
Total memory:  2 031 616, used memory:        306 152
Total memory: 30 240 768, used memory:     25 583 880
Iteration 2
Total memory: 30 240 768, used memory:     25 609 480
Total memory: 65 667 072, used memory:     52 887 728
Iteration 3
Total memory: 65 667 072, used memory:     52 945 064
java.lang.OutOfMemoryError: Java heap space | catched in createZoomedImage()
Total memory: 66 650 112, used memory:     54 151 552
Iteration 4
Total memory: 66 650 112, used memory:     54 151 552
java.lang.OutOfMemoryError: Java heap space | catched in createZoomedImage()
Total memory: 66 650 112, used memory:     58 097 496
Iteration 5
Total memory: 66 650 112, used memory:     58 097 496
java.lang.OutOfMemoryError: Java heap space | catched in createZoomedImage()
Total memory: 66 650 112, used memory:     62 057 456
Iteration 6
Total memory: 66 650 112, used memory:     62 057 456
java.lang.OutOfMemoryError: Java heap space | catched in createZoomedImage()
Total memory: 66 650 112, used memory:     66 021 048
Iteration 7
Total memory: 66 650 112, used memory:     66 021 048
java.lang.OutOfMemoryError: Java heap space | catched in main()

(красным выделено то, что пишется в System.err)


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
skhilkov
Дата 29.8.2006, 06:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 371
Регистрация: 11.4.2006
Где: TOMSK

Репутация: 2
Всего: 7



У меня тоже эта проблема была, не мог поймать эту вещь и все тут... Раньше я предполагал, что может быть эта ошибка обрабатывается внутри вышеуказанных функций, но, судя по коду LSD это не так, щас проверим  smile 

Это сообщение отредактировал(а) skhilkov - 29.8.2006, 06:45


--------------------
Кто понял жизнь, тот не спешит. 
PM MAIL   Вверх
skhilkov
Дата 29.8.2006, 07:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 371
Регистрация: 11.4.2006
Где: TOMSK

Репутация: 2
Всего: 7



LSD, работает...... у меня вот это ну никак не ловит:
Код

                  pImage = reader.read(0, param);            
        }
        catch (java.lang.NoClassDefFoundError e)
        {
            pImage = null;
        }
        catch (Exception e)
        {
            pImage = null;
        }
        catch (java.lang.OutOfMemoryError e)// никогда не заходит сюда..... зато в консоль пишет что ошибка эта была...
        {
            pImage = null;
        }



--------------------
Кто понял жизнь, тот не спешит. 
PM MAIL   Вверх
LSD
Дата 29.8.2006, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(skhilkov @  29.8.2006,  08:20 Найти цитируемый пост)
у меня вот это ну никак не ловит:

Пример дай, когда оно не ловится.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
skhilkov
Дата 29.8.2006, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 371
Регистрация: 11.4.2006
Где: TOMSK

Репутация: 2
Всего: 7



Ну вот - если эту функцию юзать, то ничего не ловится....
Код

public static BufferedImage getBufferedImageFromFile_ImageIO(InputStream inputStream, String fileName, int intFitMode, Dimension pDesiredSize, boolean bForPreview, ThumbnailProperties pProperties)
    {
        BufferedImage pImage = null;
        Dimension pImageSize = null;
        ImageReader reader = null;
        try
        {
            Thread.currentThread().setContextClassLoader(new ClassLoader(){});
            ImageInputStream stream = null;
            try
            {
                stream = ImageIO.createImageInputStream(inputStream);
            }
            catch(java.lang.NoClassDefFoundError ex)
            {
                stream = ImageIO.createImageInputStream(inputStream);
            }
            String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
            Iterator iter = ImageIO.getImageReadersByFormatName(extension);            
            int counter = 100;
            boolean hasNext = true;
            while (hasNext == true)
            {
                try
                {                    
                    reader = (ImageReader)iter.next();
                    if (reader != null)
                    {
                        break;
                    }
                    hasNext = iter.hasNext();
                    counter--;
                    if (counter < 0)
                    {
                        break;
                    }
                }
                catch(Exception e)
                {
                    hasNext = false;
                    counter--;
                }
            }
            if (reader == null)
            {
                throw new NoCodecException();
            }
            reader.setInput(stream, false, false);
            int imageWidth = reader.getWidth(0);
            int imageHeight = reader.getHeight(0);
            if (pProperties != null)
            {
                pProperties._originalImageSize = new Dimension(imageWidth, imageHeight);
            }
            //
            IIOMetadata md = null;
            try
            {
                md = reader.getImageMetadata(0);
            }
            catch(Exception e)
            {
                md = null;
            }
            if (md != null && pProperties != null)
            {
                IIOMetadataNode node = (IIOMetadataNode)md.getAsTree(md.getNativeMetadataFormatName());
                NodeList list = node.getElementsByTagName("app0JFIF");
                if (list != null && list.getLength() > 0)
                {
                    IIOMetadataNode jfif = (IIOMetadataNode)list.item(0);
                    pProperties._resUnit = jfif.getAttribute("resUnits");
                    pProperties._resX = jfif.getAttribute("Xdensity");
                    pProperties._resY = jfif.getAttribute("Ydensity");
                }
            }
            //
            pImageSize = getDimensionAccordingToFitMode(intFitMode, pDesiredSize, new Dimension(imageWidth, imageHeight), bForPreview);
            ImageReadParam param = reader.getDefaultReadParam();
            int horzSubsampling = 0;
            int vertSubsampling = 0;
            int subsampling = 1;
            
                                                horzSubsampling = (int) Math.floor((float) imageWidth / (float) pImageSize.width/* / 2.0 !!!!*/);
            vertSubsampling = (int) Math.floor((float) imageHeight / (float) pImageSize.height/* / 2.0 !!!!*/);
            subsampling = Math.min(horzSubsampling, vertSubsampling);
            int realSubsampling = Math.max(1, subsampling);
                param.setSourceSubsampling(realSubsampling, realSubsampling, 0, 0);
            }
            pImage = reader.read(0, param);    
            pImage.getWidth(null);
        }
        catch (java.lang.NoClassDefFoundError e)
        {
            pImage = null;
        }
        catch (Exception e)
        {            
            pImage = null;
        }
        catch (java.lang.OutOfMemoryError e)
        {
            System.err.println("OutOfMemoryError catched in function ImageIO.read()");
            pImage = null;
        }
        finally
        {
            if (reader != null)
            {
                reader.dispose();
                reader = null;
            }
        }
        return pImage;
    }



--------------------
Кто понял жизнь, тот не спешит. 
PM MAIL   Вверх
LSD
Дата 30.8.2006, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



skhilkov, твой код не компилируется:
1. он не сбалансирован по скобкам
2. неизвестно что за класс ThumbnailProperties


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0581 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.