Название: QImage: out of memory, returning null image Отправлено: nozog от Ноябрь 25, 2009, 11:44 Здравствуйте.
Создал класс занимающийся увеличением картинки. Вызывая много раз подряд слот zoomIn() руками через сигнал pushbutton Clicked (не в цикле) происходит следующее: изображение увеличивается до определенного значения коэффициента масштабирования(zoom_value), далее выводится сообщение: "QImage: out of memory, returning null image" при попытке увеличить исходное изображение на предыдущее значение коэффициента масштабирования(zoom_value) сообщение повторяется пока коэффициент масштабирования не станет равен 1/zoom_value Задача была создать слот с логигой: увеличить изображение если невозможно то вернуть предыдущее увеличение Пожалуйста подскажите что не так сделал и в чем ошибка, почему после "QImage: out of memory, returning null image" увеличивая на предыдуший коэффициент сново выводится "QImage: out of memory, returning null image" Спасибо ===================================== Вот класс ===================================== Код: class Viewer : public QWidget{ вот лог с коментариями ===================================== Код: transform image[ QSize(800, 600) ] to [ QSize(1040, 780) ] Название: Re: QImage: out of memory, returning null image Отправлено: Igors от Ноябрь 25, 2009, 16:23 Код: t_image->operator = (*image); Код: *t_image = *image; А главное Цитировать QImage & QImage::operator= ( const QImage & image ) А это значит что оба t_image и image будут ссылаться на те же данные. ПоэтомуAssigns a shallow copy of the given image to this image and returns a reference to this image. Код: *t_image = image->copy(); // если уж хочется скопировать, хотя не видно зачем Название: Re: QImage: out of memory, returning null image Отправлено: nozog от Ноябрь 26, 2009, 14:57 Код: t_image->operator = (*image); Код: *t_image = *image; Согласен но не суть. А главное Цитировать QImage & QImage::operator= ( const QImage & image ) А это значит что оба t_image и image будут ссылаться на те же данные. ПоэтомуAssigns a shallow copy of the given image to this image and returns a reference to this image. Код: *t_image = image->copy(); // если уж хочется скопировать, хотя не видно зачем результат тотже хотел сделать zoom в painEvent что то типа: Код: painter.begin(this); но подумал что это долго для больших изображений Название: Re: QImage: out of memory, returning null image Отправлено: Igors от Ноябрь 26, 2009, 17:50 У меня впечатление что если Ваш текст "причесать", то он и будет работать как надо. Выкладывайте компилябельный проект, попробуем
Название: Re: QImage: out of memory, returning null image Отправлено: nozog от Ноябрь 27, 2009, 14:41 У меня впечатление что если Ваш текст "причесать", то он и будет работать как надо. Выкладывайте компилябельный проект, попробуем Выделил в отдельный проект Пожалуйста, пробуйте, только имя исходного изображения измените. Название: Re: QImage: out of memory, returning null image Отправлено: Igors от Ноябрь 27, 2009, 18:12 Выделил в отдельный проект Подрихтовал под свой вкус, поставил ограничители на zoom (attachment). Работает нормально, памяти ест сколько положено. Проблема о которой Вы говорили - да, видел, но исчезла сразу как только я убрал член класса QPainter (использовать др. painter кроме стекового = верный путь к неприятностям). Пожалуйста, пробуйте, только имя исходного изображения измените. Название: Re: QImage: out of memory, returning null image Отправлено: nozog от Ноябрь 27, 2009, 21:32 спасибо, в понедельник посмотрю
Название: Re: QImage: out of memory, returning null image Отправлено: nozog от Ноябрь 30, 2009, 10:36 Igors, возникло несколько вопросов:
1. использовать др. painter кроме стекового = верный путь к неприятностям можно по подробнее почему именно так2. почему QImage image а не QImage *image с выделение памяти в конструкторе 3. зачем ограничение в 1Gb 4. если t_image.isNull() то должно остаться предыдущее значение, а не исходное, тогда: Код: if (t_image.isNull()){ переходит в что-то типа: Код: if(t_image.isNull()){ и далее в Код: while(t_image.isNull()){ Название: Re: QImage: out of memory, returning null image Отправлено: Igors от Ноябрь 30, 2009, 11:34 Igors, возникло несколько вопросов: 1) Не могу объяснить "строго научно/теоретически" но на практике рисование всегда начинается с нуля и заканчивается полным освобождением задействованных ресурсов. В том же Вындоуз - начали рисовать, взяли контекст GetClientDC(), отрисовали, освободили ReleaseDC(). Можно хранить атрибуты (браши, цвета и.т.п) но никак не контекст. При каждом новом рисовании все атрибуты заряжаются в контекст с нуля. Как показала жизнь - остальное не работает.1. использовать др. painter кроме стекового = верный путь к неприятностям можно по подробнее почему именно так2. почему QImage image а не QImage *image с выделение памяти в конструкторе 3. зачем ограничение в 1Gb 4. если t_image.isNull() то должно остаться предыдущее значение, а не исходное, тогда: 2) Можно конечно и указатель но член-объект в данном случае естественнее. Вы собираетесь обыгрывать ситуацию когда t_image = 0? Нет и не предвидится, этот член класса всегда существует. Зачем тогда все время приклеивать к указателю звездочку? 3) По крайней мере не все ОС могут выделять блок памяти больше 1 Gb (даже если она есть физически), поэтому незачем нарываться на отказ памяти. Заметим что для рисования еще раз потребуется такой же блок. 4) Не делите на 1.3 а запоминайте предыдущий zoom и используйте его. Дело темное что произойдет после отказа памяти и все ли Qt корректно восстановит. Лучше "начать от печки" если это случилось Название: Re: QImage: out of memory, returning null image Отправлено: nozog от Декабрь 01, 2009, 10:55 Вышел из ситуации так:
Код: void Widget::paintEvent ( QPaintEvent * event ) { Все как и хотел, даже второй QImage не понадобился,добавил вращение. Проявился такой эффект: Если изображение меньше виджета то при вращении на +- 90 все нормально, при +- 180 картинка прилепает в левый верхний угол; скорее всего ошибка у меня но что-то никак не могу найти, может глянете в продолжение беседы ? Спасибо. Название: Re: QImage: out of memory, returning null image Отправлено: Igors от Декабрь 01, 2009, 13:57 Вышел из ситуации так: Смотрим: QPainter член класса. Вызов painter.end() отсутствует. Под вращением понимаются повороты на 90/180 градусов каждый из которых обрабатывается отдельно. Хмм... И кто Вам сказал что угол может быть только до 360? :) Как Вы написали, так оно и будет работать. Пишите аккуратно и старательно - и все получится.Код: void Widget::paintEvent ( QPaintEvent * event ) { Все как и хотел, даже второй QImage не понадобился,добавил вращение. Проявился такой эффект: Если изображение меньше виджета то при вращении на +- 90 все нормально, при +- 180 картинка прилепает в левый верхний угол; скорее всего ошибка у меня но что-то никак не могу найти, может глянете в продолжение беседы ? Спасибо. Название: Re: QImage: out of memory, returning null image Отправлено: nozog от Декабрь 02, 2009, 11:14 Смотрим: QPainter член класса. Вызов painter.end() отсутствует. согласен, забыл. Под вращением понимаются повороты на 90/180 градусов каждый из которых обрабатывается отдельно.Хмм... можно все вместе обаботать,но это дело вкуса и опытаИ кто Вам сказал что угол может быть только до 360? :) нужно вращение только на угол кратный 90 + приведение угла в методе fitRotate() из чего и следуетутверждение о возможных значениях углов. Как Вы написали, так оно и будет работать. Пишите аккуратно и старательно - и все получится. Истина. В методе fitRotate() заменил setGeometry() на resize() прыжки в левый верхний угол прекратились. Возник вопрос: Почему если W и H изменяютя перед каждым вызовом QWidget setGeometry(0,0,W,H), то все нормально центруется, если W и H НЕ изменять - прыжок в левый верхний угол, хотя его родителю QScrollArea сказано setAlignment(Qt::AlignCenter), с resize() такого нет. Название: Re: QImage: out of memory, returning null image Отправлено: Igors от Декабрь 02, 2009, 13:02 Под вращением понимаются повороты на 90/180 градусов каждый из которых обрабатывается отдельно.Хмм... можно все вместе обаботать,но это дело вкуса и опытаИ кто Вам сказал что угол может быть только до 360? :) нужно вращение только на угол кратный 90 + приведение угла в методе fitRotate() из чего и следуетутверждение о возможных значениях углов. Возник вопрос: Открываем исходники Qt (а еще лучше шагаем в отладчике) и смотрим почему :) (хотя это может быть непросто)Почему если W и H изменяютя перед каждым вызовом QWidget setGeometry(0,0,W,H), то все нормально центруется, если W и H НЕ изменять - прыжок в левый верхний угол, хотя его родителю QScrollArea сказано setAlignment(Qt::AlignCenter), с resize() такого нет. Название: Re: QImage: out of memory, returning null image Отправлено: nozog от Декабрь 03, 2009, 07:58 Открываем исходники Qt (а еще лучше шагаем в отладчике) и смотрим почему :) (хотя это может быть непросто) Ожидал что-то вроде: "читай внимательнее хелп" или как говориться "RTFM" ;)Кстати, копался в исходниках на предмет сообщения "QImage: out of memory, returning null image", но ничего путного так и не нашел. Толи лыжи не едут толи я плохо искал. Пошел разбираться с setGeometry()... |