Russian Qt Forum
Февраль 10, 2012, 15:26
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Мультимедиа
(Модератор:
Sergeich
) >
QImage: out of memory, returning null image
Страниц: [
1
]
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: QImage: out of memory, returning null image (Прочитано 2869 раз)
nozog
Гость
QImage: out of memory, returning null image
«
:
Ноябрь 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{
...
public slots:
void zoomIn();
protected:
QImage *image;
QImage *t_image;
QPainter painter;
void paintEvent(QPaintEvent * event);
qreal
zoom_value; // коэф. масштабирования
};
--------------------------------
Viewer::Viewer(QWidget *parent) : QWidget(parent){
zoom_value = 1.0;
image
= new QImage();
t_image
= new QImage();
if(image->load("...jpg")){
t_image->operator = (*image);
if(!t_image->isNull()){
setGeometry(QRect(0,0,t_image->width(),t_image->height()));
}
}
}
void Viewer::paintEvent(QPaintEvent *event){
qDebug()<<"paint:";
if(!t_image->isNull()){
qDebug()<<" draw image";
painter.begin(this);
painter.drawImage(0,0,*t_image);
painter.end();
}
else
qDebug()<<" image is null";
}
void Viewer::zoomIn(){
if(!t_image->isNull()){
QMatrix matrix;
zoom_value*=1.3;
t_image->operator = (image->transformed(matrix.scale(zoom_value,zoom_value)));
while(t_image->isNull()){
zoom_value/=1.3;
qDebug()<<" image is null, zoom value = "<<zoom_value;
t_image->operator =(image->transformed(matrix.scale(zoom_value,zoom_value)));
}
qDebug()<<"transform image["<<image->size()<<"] to ["<<t_image->size()<<"]";
qDebug()<<" image is OK, zoom value = "<<zoom_value;
setGeometry(QRect(0,0,t_image->width(),t_image->height()));
update();
}
}
=====================================
вот лог с коментариями
=====================================
Код:
transform image[ QSize(800, 600) ] to [ QSize(1040, 780) ]
image is OK, zoom value = 1.3
paint:
draw image
// изображение увеличелось
...
transform image[ QSize(800, 600) ] to [ QSize(11029, 8272) ]
image is OK, zoom value = 13.7858
paint:
draw image
// изображение увеличелось
QImage: out of memory, returning null image
image is null, zoom value = 13.7858
...
QImage: out of memory, returning null image
image is null, zoom value = 0.0725382
transform image[ QSize(800, 600) ] to [ QSize(14337, 10753) ]
image is OK, zoom value = 0.0725382
paint:
draw image
// изображение увеличелось!!!
transform image[ QSize(800, 600) ] to [ QSize(75, 57) ]
image is OK, zoom value = 0.0942996
paint:
draw image
// изображение уменьшилось от исходного в zoom value = 0.0942996 раз
transform image[ QSize(800, 600) ] to [ QSize(98, 74) ]
image is OK, zoom value = 0.122589
paint:
draw image
// изображение увеличелось
итд
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 2909
Re: QImage: out of memory, returning null image
«
Ответ #1 :
Ноябрь 25, 2009, 16:23 »
Код:
t_image->operator = (*image);
...
t_image->operator =(image->transformed(matrix.scale(zoom_value,zoom_value)));
Зачем такие выкрутасы? Почему не
Код:
*t_image = *image;
...
*t_image = image->transformed(matrix.scale(zoom_value,zoom_value);
?
А главное
Цитировать
QImage & QImage::operator= ( const QImage & image )
Assigns
a shallow copy
of the given image to this image and returns a reference to this image.
А это значит что оба t_image и image будут ссылаться на те же данные. Поэтому
Код:
*t_image = image->copy(); // если уж хочется скопировать, хотя не видно зачем
...
*t_image = image->transformed(matrix.scale(zoom_value,zoom_value);
Записан
nozog
Гость
Re: QImage: out of memory, returning null image
«
Ответ #2 :
Ноябрь 26, 2009, 14:57 »
Цитата: Igors от Ноябрь 25, 2009, 16:23
Код:
t_image->operator = (*image);
...
t_image->operator =(image->transformed(matrix.scale(zoom_value,zoom_value)));
Зачем такие выкрутасы? Почему не
Код:
*t_image = *image;
...
*t_image = image->transformed(matrix.scale(zoom_value,zoom_value);
?
Согласен но не суть.
Цитата: Igors от Ноябрь 25, 2009, 16:23
А главное
Цитировать
QImage & QImage::operator= ( const QImage & image )
Assigns
a shallow copy
of the given image to this image and returns a reference to this image.
А это значит что оба t_image и image будут ссылаться на те же данные. Поэтому
Код:
*t_image = image->copy(); // если уж хочется скопировать, хотя не видно зачем
...
*t_image = image->transformed(matrix.scale(zoom_value,zoom_value);
результат тотже
хотел сделать zoom в painEvent что то типа:
Код:
painter.begin(this);
painter.scale(zoom_value,zoom_value)
painter.drawImage(0,0,*t_image);
painter.end();
но подумал что это долго для больших изображений
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 2909
Re: QImage: out of memory, returning null image
«
Ответ #3 :
Ноябрь 26, 2009, 17:50 »
У меня впечатление что если Ваш текст "причесать", то он и будет работать как надо. Выкладывайте компилябельный проект, попробуем
Записан
nozog
Гость
Re: QImage: out of memory, returning null image
«
Ответ #4 :
Ноябрь 27, 2009, 14:41 »
Цитата: Igors от Ноябрь 26, 2009, 17:50
У меня впечатление что если Ваш текст "причесать", то он и будет работать как надо. Выкладывайте компилябельный проект, попробуем
Выделил в отдельный проект
Пожалуйста, пробуйте,
только имя исходного изображения измените.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 2909
Re: QImage: out of memory, returning null image
«
Ответ #5 :
Ноябрь 27, 2009, 18:12 »
Цитата: nozog от Ноябрь 27, 2009, 14:41
Выделил в отдельный проект
Пожалуйста, пробуйте,
только имя исходного изображения измените.
Подрихтовал под свой вкус, поставил ограничители на zoom (attachment). Работает нормально, памяти ест сколько положено. Проблема о которой Вы говорили - да, видел, но исчезла сразу как только я убрал член класса QPainter (использовать др. painter кроме стекового = верный путь к неприятностям).
Записан
nozog
Гость
Re: QImage: out of memory, returning null image
«
Ответ #6 :
Ноябрь 27, 2009, 21:32 »
спасибо, в понедельник посмотрю
Записан
nozog
Гость
Re: QImage: out of memory, returning null image
«
Ответ #7 :
Ноябрь 30, 2009, 10:36 »
Igors, возникло несколько вопросов:
1.
Цитата: Igors от Ноябрь 27, 2009, 18:12
использовать др. painter кроме стекового = верный путь к неприятностям
можно по подробнее почему именно так
2. почему QImage image а не QImage *image с выделение памяти в конструкторе
3. зачем ограничение в 1Gb
4. если t_image.isNull() то должно остаться предыдущее значение, а не исходное,
тогда:
Код:
if (t_image.isNull()){
zoom_value = 1.0;
qDebug() << " image is null, zoom value = " << zoom_value;
t_image = image;
}
else {
CODE
}
переходит в что-то типа:
Код:
if(t_image.isNull()){
zoom_value/=1.3;
qDebug()<<" image is null, zoom value = "<<zoom_value;
t_image = image.transformed(matrix.scale(zoom_value, zoom_value));
}
//else {
CODE
//}
и далее в
Код:
while(t_image.isNull()){
zoom_value/=1.3;
qDebug()<<" image is null, zoom value = "<<zoom_value;
t_image = image.transformed(matrix.scale(zoom_value, zoom_value));
}
//else {
CODE
//}
так как при этом возвращается исходная проблема
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 2909
Re: QImage: out of memory, returning null image
«
Ответ #8 :
Ноябрь 30, 2009, 11:34 »
Цитата: nozog от Ноябрь 30, 2009, 10:36
Igors, возникло несколько вопросов:
1.
Цитата: Igors от Ноябрь 27, 2009, 18:12
использовать др. painter кроме стекового = верный путь к неприятностям
можно по подробнее почему именно так
2. почему QImage image а не QImage *image с выделение памяти в конструкторе
3. зачем ограничение в 1Gb
4. если t_image.isNull() то должно остаться предыдущее значение, а не исходное,
тогда:
1) Не могу объяснить "строго научно/теоретически" но на практике рисование всегда начинается с нуля и заканчивается полным освобождением задействованных ресурсов. В том же Вындоуз - начали рисовать, взяли контекст GetClientDC(), отрисовали, освободили ReleaseDC(). Можно хранить атрибуты (браши, цвета и.т.п) но никак не контекст. При каждом новом рисовании все атрибуты заряжаются в контекст с нуля. Как показала жизнь - остальное не работает.
2) Можно конечно и указатель но член-объект в данном случае естественнее. Вы собираетесь обыгрывать ситуацию когда t_image = 0? Нет и не предвидится, этот член класса всегда существует. Зачем тогда все время приклеивать к указателю звездочку?
3) По крайней мере не все ОС могут выделять блок памяти больше 1 Gb (даже если она есть физически), поэтому незачем нарываться на отказ памяти. Заметим что для рисования еще раз потребуется такой же блок.
4) Не делите на 1.3 а запоминайте предыдущий zoom и используйте его. Дело темное что произойдет после отказа памяти и все ли Qt корректно восстановит. Лучше "начать от печки" если это случилось
Записан
nozog
Гость
Re: QImage: out of memory, returning null image
«
Ответ #9 :
Декабрь 01, 2009, 10:55 »
Вышел из ситуации так:
Код:
void Widget::paintEvent ( QPaintEvent * event ) {
...
painter.drawImage(QRect(0,0,width(),height()),image);
...
}
Все как и хотел, даже второй QImage не понадобился,добавил вращение.
Проявился такой эффект:
Если изображение меньше виджета то
при вращении на +- 90 все нормально,
при +- 180 картинка прилепает в левый верхний угол;
скорее всего ошибка у меня но что-то никак не могу найти,
может глянете в продолжение беседы ?
Спасибо.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 2909
Re: QImage: out of memory, returning null image
«
Ответ #10 :
Декабрь 01, 2009, 13:57 »
Цитата: nozog от Декабрь 01, 2009, 10:55
Вышел из ситуации так:
Код:
void Widget::paintEvent ( QPaintEvent * event ) {
...
painter.drawImage(QRect(0,0,width(),height()),image);
...
}
Все как и хотел, даже второй QImage не понадобился,добавил вращение.
Проявился такой эффект:
Если изображение меньше виджета то
при вращении на +- 90 все нормально,
при +- 180 картинка прилепает в левый верхний угол;
скорее всего ошибка у меня но что-то никак не могу найти,
может глянете в продолжение беседы ?
Спасибо.
Смотрим: QPainter член класса. Вызов painter.end() отсутствует. Под вращением понимаются повороты на 90/180 градусов каждый из которых обрабатывается отдельно. Хмм... И кто Вам сказал что угол может быть только до 360?
Как Вы написали, так оно и будет работать. Пишите аккуратно и старательно - и все получится.
Записан
nozog
Гость
Re: QImage: out of memory, returning null image
«
Ответ #11 :
Декабрь 02, 2009, 11:14 »
Цитата: Igors от Декабрь 01, 2009, 13:57
Смотрим: QPainter член класса. Вызов painter.end() отсутствует.
согласен, забыл.
Цитата: Igors от Декабрь 01, 2009, 13:57
Под вращением понимаются повороты на 90/180 градусов каждый из которых обрабатывается отдельно.Хмм...
можно все вместе обаботать,но это дело вкуса и опыта
Цитата: Igors от Декабрь 01, 2009, 13:57
И кто Вам сказал что угол может быть только до 360?
нужно вращение только на угол кратный 90 + приведение угла в методе fitRotate() из чего и следует
утверждение о возможных значениях углов.
Цитата: Igors от Декабрь 01, 2009, 13:57
Как Вы написали, так оно и будет работать. Пишите аккуратно и старательно - и все получится.
Истина. В методе fitRotate() заменил setGeometry() на resize() прыжки в левый верхний угол прекратились.
Возник вопрос:
Почему если W и H изменяютя перед каждым вызовом QWidget setGeometry(0,0,W,H),
то все нормально центруется, если W и H НЕ изменять - прыжок в левый верхний угол,
хотя его родителю QScrollArea сказано setAlignment(Qt::AlignCenter),
с resize() такого нет.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 2909
Re: QImage: out of memory, returning null image
«
Ответ #12 :
Декабрь 02, 2009, 13:02 »
Цитата: nozog от Декабрь 02, 2009, 11:14
Цитата: Igors от Декабрь 01, 2009, 13:57
Под вращением понимаются повороты на 90/180 градусов каждый из которых обрабатывается отдельно.Хмм...
можно все вместе обаботать,но это дело вкуса и опыта
Цитата: Igors от Декабрь 01, 2009, 13:57
И кто Вам сказал что угол может быть только до 360?
нужно вращение только на угол кратный 90 + приведение угла в методе fitRotate() из чего и следует
утверждение о возможных значениях углов.
Цель не в том чтобы похвалиться "я, мол, любые вращения делаю". Просто гораздо проще и лучше реализовать одну операцию (вращение) вместо того чтобы разбирать N ее частных случаев. Разумеется, для пользователя/преподавателя Вы оставите только нужные углы.
Цитата: nozog от Декабрь 02, 2009, 11:14
Возник вопрос:
Почему если W и H изменяютя перед каждым вызовом QWidget setGeometry(0,0,W,H),
то все нормально центруется, если W и H НЕ изменять - прыжок в левый верхний угол,
хотя его родителю QScrollArea сказано setAlignment(Qt::AlignCenter),
с resize() такого нет.
Открываем исходники Qt (а еще лучше шагаем в отладчике) и смотрим почему
(хотя это может быть непросто)
Записан
nozog
Гость
Re: QImage: out of memory, returning null image
«
Ответ #13 :
Декабрь 03, 2009, 07:58 »
Цитата: Igors от Декабрь 02, 2009, 13:02
Открываем исходники Qt (а еще лучше шагаем в отладчике) и смотрим почему
(хотя это может быть непросто)
Ожидал что-то вроде: "читай внимательнее хелп" или как говориться "RTFM"
Кстати, копался в исходниках на предмет сообщения "QImage: out of memory, returning null image",
но ничего путного так и не нашел. Толи лыжи не едут толи я плохо искал.
Пошел разбираться с setGeometry()...
Записан
Страниц: [
1
]
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> Печать
=> Интернационализация, локализация
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
=> Архив
===> Программирование
=====> Python
===> Веб программирование
=====> PHP, PERL, CGI
Загружается...
одеяла купить