Russian Qt Forum

Qt => Общие вопросы => Тема начата: alex12 от Апрель 06, 2009, 06:43



Название: Генерация картинки в файл без X-сервера
Отправлено: alex12 от Апрель 06, 2009, 06:43
Нужно написать утилитку коммандной строки, которая создает файл с картинкой.
Если использовать модуль QtGui и создавать QApplication, то все работает на ура.

Предполагается использовать эту утилитку для построения web-интерфейса в связке с php и apache под Linux. И ничего не работает. Похоже возникает ошибка типа "Can not connect to X server".

Вопрос, как быть? Возможно ли такое сделать в пинципе? Можно ли обойтись без X-сервера, но при этом использовать функции рисования по QImage?

Простейший тест:
Код:
#include <QtGui>

int main( int argc, char **argv )
{
  QApplication app( argc, argv );

  QImage image( 300,200, QImage::Format_RGB32 );
  image.fill(0xFFFFFF);
  QPainter painter( &image );
  painter.drawText(100,100,"Hello, world!");
 
  image.save( "test.png", "PNG" );
  return 0;
}
Код:
TEMPLATE = app
CONFIG += console
SOURCES = test.cpp


Название: Re: Генерация картинки в файл без X-сервера
Отправлено: BRE от Апрель 06, 2009, 07:43
Если использовать модуль QtGui и создавать QApplication, то все работает на ура.
А если заменить QApplication на QCoreApplication?


Название: Re: Генерация картинки в файл без X-сервера
Отправлено: spirit от Апрель 06, 2009, 08:22
Если использовать модуль QtGui...
правильно, т.к. этот класс является частью QtGui.
а с использование QCoreApplication ничего не выйдет,
нужно создавать QApplication, т.к. там идет инифиализация необходимых структур,
так что ваш код правильный.


Название: Re: Генерация картинки в файл без X-сервера
Отправлено: alex12 от Апрель 06, 2009, 11:24
Так есть ли шанс запустить подобный пример на Linux сервере без X-ов?


Название: Re: Генерация картинки в файл без X-сервера
Отправлено: spirit от Апрель 06, 2009, 11:25
попробуйте и сообщите нам результат :)


Название: Re: Генерация картинки в файл без X-сервера
Отправлено: crackedmind от Апрель 06, 2009, 11:52
Код:
int main( int argc, char **argv )
{
  QCoreApplication app( argc, argv );

  QImage image( 300,200, QImage::Format_RGB32 );
  image.fill(0xFFFFFF);
  QPainter painter( &image );
  painter.drawText(100,100,"Hello, world!");
 
  image.save( "test.png", "PNG" );
  return 0;
}
под виндой крэшится... так что думаю не выйдет :) может стоит использовать что-то типа imagemagick?


Название: Re: Генерация картинки в файл без X-сервера
Отправлено: Sergeich от Апрель 06, 2009, 12:58
Попробуй так:
Код:
#include <QImage>
#include <QPainter>
#include <QApplication>

int main( int argc, char** argv )
{
  QApplication app( argc, argv, false );

  QImage image( 400, 300, QImage::Format_RGB32 );
  QFont font( "Helvetica", 24 );   
  QPainter painter( &image );

  painter.setFont( font );
  painter.setPen( Qt::black );
  painter.fillRect( image.rect(), Qt::white );
  painter.drawText( image.rect(), Qt::AlignCenter, "Hello, world!" );
  image.save( "test.png", "PNG" );

  return 0;
}
Еще глянь сюды (http://doc.trolltech.com/4.5/qapplication.html#QApplication-2) и сюды (http://doc.trolltech.com/4.5/threads.html#painting-in-threads)


Название: Re: Генерация картинки в файл без X-сервера
Отправлено: alex12 от Апрель 06, 2009, 15:26
Попробуй так:
Код:
#include <QImage>
#include <QPainter>
#include <QApplication>
...
QApplication app( argc, argv, false );
...
Еще глянь сюды (http://doc.trolltech.com/4.5/qapplication.html#QApplication-2) и сюды (http://doc.trolltech.com/4.5/threads.html#painting-in-threads)

В яблочко! То, что надо. Спасибо. Проверил на Linux сервере. Связка с PHP рабтает. Можно делать динамические картинки для web-интерфейса!

Теперь от тестов к реальной задаче. Все началось с того, что есть программа с активным использованием библиотеки Qwt для построения кучи графиков. Так вот нужно сделать вывод Qwt-графиков в виде картинок. Вот тестовый пример:

Код:
#include <QApplication>
#include <QImage>
#include <QPainter>

#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_grid.h>
#include <qwt_legend.h>

static void output( QwtPlot *plot )
{
  const int width  = 600;
  const int height = 400;

  QImage image( width,height, QImage::Format_RGB32 );
  image.fill(0xFFFFFF);
  QPainter painter( &image );
  plot->print( &painter, QRect(10,10,width-20,height-20) );
  image.save( "test.png", "PNG" );
}

static void setData( QwtPlotCurve *curve )
{
  QVector<double> x,y;
  for(int i=0;i<1000;i++)
  { x << i;
    y << sin((double)i/1000*2*3.1415926);
  }
  curve->setData( x,y );
}

int main( int argc, char **argv )
{
  QApplication app( argc, argv, true );

  QwtPlot plot;

  QwtPlotGrid grid;
  grid.enableXMin(true);
  grid.enableYMin(true);
  grid.setMajPen(QPen(Qt::black, 1, Qt::DotLine));
  grid.setMinPen(QPen(Qt::gray, 1, Qt::DotLine));
  grid.attach( &plot );

  plot.setCanvasBackground(QColor("linen"));
  plot.setAxisScale(QwtPlot::yLeft,-1,1);
  plot.insertLegend(new QwtLegend, QwtPlot::BottomLegend);

  QwtPlotCurve curve;
  curve.setPen(QPen(Qt::darkBlue,2));
  curve.setTitle("sin"); 
  setData( &curve );
  curve.attach( &plot );

  app.processEvents();

  output( &plot );

  return 0;
}
Код:
TEMPLATE = app
CONFIG  += console
SOURCES = test.cpp

win32{
INCLUDEPATH += $$[QT_INSTALL_PREFIX]/include/Qwt
LIBS        += -lqwt5
}
unix{
INCLUDEPATH += /usr/local/qwt/include
LIBS        += -lqwt
}

К сожалению, здесь фокус с QApplication app( argc, argv, false ); не проходит. Он ругается, очивидно, на  QwtPlot plot; следующим образом:
Код:
QWidget: Cannot create a QWidget when no GUI is being used

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Его можно понять: QwtPlot наследник QWidget'а. Собственно вывод на QImage сделан как вызов plot->print( &painter, QRect(10,10,width-20,height-20) ); и явно свойства QWidget'а не используются.

Может кто знает, как в рамках Qwt сделать вывод без создания наследников QWidget'? В крайнем случае придется делать вывод графиков вручную, а этого не очень хочется...


Название: Re: Генерация картинки в файл без X-сервера
Отправлено: spirit от Апрель 06, 2009, 16:42
если дружишь с английским, то можешь обратиться к разработчику Qwt на qtcentre.org в разделе "Qwt". зовут его Uwe.


Название: Re: Генерация картинки в файл без X-сервера
Отправлено: Sergeich от Апрель 06, 2009, 18:18
У QwtPlotItem, наследниками к-ого являются QwtPlotCurve и QwtPlotGrid, есть метод void draw (QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRect &canvasRect) const, попробуй выводить им.


Название: Re: Генерация картинки в файл без X-сервера
Отправлено: Sergeich от Апрель 06, 2009, 23:58
Поковырял исходники qwt, и понял, что оно так, к сожалению, не получиться. В QwtPlotCurve::draw, если нет плота вызывается return :( Можно, конечно юзать другие методы, но думаю это не выход. Я бы замутил либу на основе QGraphicsScene, попиздив часть кода из qwt. Через QGraphicsScene::render можно рисовать хоть на принтере, хоть в SVG.