Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 [2] 3 4  Все   Вниз
  Печать  
Автор Тема: Избавится от циклов при рисовании картинки в Qt  (Прочитано 86412 раз)
0 Пользователей и 1 Гость смотрят эту тему.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #30 : 21-05-2013 06:39 » 

Есть только две:

Код:
QImage fromData ( const uchar * data, int size, const char * format = 0 )
QImage fromData ( const QByteArray & data, const char * format = 0 )

Тогда почему я выбираю

Код:
QImage fromData ( const QByteArray & data, const char * format = 0 )

А выскакивает ошибка:
invalid conversion from 'char*' to 'const uchar*'
initializing argument 1 of 'static QImage QImage::fromData(const uchar *, int, const char*)'

Почему так?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #31 : 21-05-2013 06:58 » 

покажи, где ты это выбираешь ? И как ты это делаешь
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #32 : 21-05-2013 07:08 » 

покажи, где ты это выбираешь ? И как ты это делаешь

Прикрепляю картинку, как я выбираю. Если что не понятно будет я поясню.



* SelectfromData.jpg (57.18 Кб - загружено 1025 раз.)
Записан
darkelf
Молодой специалист

no
Offline Offline

« Ответ #33 : 21-05-2013 07:16 » 

zuze, это потому, что там ещё длину массива надо передать. (Ты прототипы функций то гляди)

а я предлагаю использовать метод, где передаётся сразу ссылка на QByteArray

Я не могу понять, выбираю "QImage::fromData(const uchar *, const char*)", а при компиляции запускается "QImage::fromData(const uchar *, int, const char*)", почему же так происходит?
Я посмотрел документацию, есть следующий функции:
Код:
QImage fromData ( const uchar * data, int size, const char * format = 0 )
QImage fromData ( const QByteArray & data, const char * format = 0 )
функции
Код:
QImage::fromData(const uchar *, const char*)
нет, так-что попробуйте, как советовал Алексей++, либо напрямую передавать  QByteArray & data, либо узнайте его длину, через mydata.size(), что-то типа:
Код:
im = QImage::fromData((const uchar*)mydata.data(), mydata.size(), &f);
или
im = QImage::fromData(&mydata, &f);
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #34 : 21-05-2013 07:29 » 

Прикрепляю картинку, как я выбираю. Если что не понятно будет я поясню.
убил Улыбаюсь

darkelf, только в самой последней строке mydata надо без амперсенда
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #35 : 21-05-2013 07:48 » 

darkelf, только в самой последней строке mydata надо без амперсенда

да делал я так уже:

Код:
im = QImage::fromData(mydata, &f);

А в результате ошибка:
conversion from 'qbytearray' to 'const uchar*' is ambiguous
candidates are: QByteArray::operator QNotImplicitBoolCast() const <near match>
QByteArray::operator const void*() const <near match>
QByteArray::operator const char*() const <near match>

А если делаю так:

Код:
im = QImage::fromData((const uchar*)mydata.data(), mydata.size(), &f);

То всё равно ошибка:
no matching function for call to 'QImage::fromData(const uchar*, int, QImage::Format*)'
candidates are: static QImage QImage::fromData(const uchar*, int, const char*)
static QImage QImage::fromData(const QByteArray&, const char*)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #36 : 21-05-2013 07:54 » 

zuze, прицепи проект, что-то совсем непонятно
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #37 : 21-05-2013 10:14 » 

zuze, прицепи проект, что-то совсем непонятно

Прикрепляю проект. Прошу прощения, что я не могу Вам оригинал двоичного (бинарного) файла предоставить. В замен него в проекте лежит с таким же именем, расширением и количества байт файл. Я его создал лично, в нём байты произвольного значения, но для конкретной цели подойдёт этот файл.

* of.rar (39.55 Кб - загружено 998 раз.)
Записан
darkelf
Молодой специалист

no
Offline Offline

« Ответ #38 : 21-05-2013 13:33 » 

zuze, попробуйте убрать параметр format вообще, похоже Qt там ожидает строку, типа "JPG", "BMP" и пр.
Код:
im = QImage::fromData(mydata);
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #39 : 21-05-2013 13:44 » 

хм, в общем, оставь так:

im = QImage::fromData(mydata, 0);

формат там задаётся как строка (например "JPG") , а если указать 0, он сам будет разбираться

И ещё - добавь реализации для слотов
    void MyExit();  
    void MyFile();

а то не сможешь собрать

Добавлено через 23 секунды:
darkelf, ага, тоже уже выяснил )
« Последнее редактирование: 21-05-2013 13:44 от Алексей1153 » Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #40 : 22-05-2013 06:29 » 

Алексей++, darkelf, большое спасибо, ошибки исчезли, но к сожалению на экран ни чего не выводится, хотя должно рисоваться тоненькая линия по значениям. Прямоугольная область пока не должна рисоваться пока я не сделал "переформатирование". Я подумал может на светлом окне не видно и я сделал чёрное окно, всё равно не видно. На всякий случай прикреплю проект. По идее сейчас линия тоненькая должна рисоваться и уходить за размер окна, так как значений очень много.
И если что тут ещё приведу главный код проекта:
Код:
#include "of.h"
#include "ui_of.h"

#include <io.h>
#include <QByteArray>
#include <QFile>

#include <QPainter>
#include <QImage>

#include <QDebug>

QImage im(720, 492, QImage::Format_ARGB32);

of::of(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::of)
{
    ui->setupUi(this);

    // Для кодировки русского языка на виджетах
    QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale()); // Без этого кодировки БД не работает
    QTextCodec::setCodecForTr(QTextCodec::codecForName("CP-1251"));

    this->

    // Выход программы
    connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(MyExit()));
}
of::~of()
{
    delete ui;
}
// Открытие файла
void of::MyDraw()
{
    chdir("file");
    QFile file("1.dat");

    if (file.open(file.ReadOnly))
    {
        QByteArray mydata = file.readAll();
        file.close();

        mydata.remove(0, 8);

        //здесь переформатирование (Пока не понимаю, как сделать)

        im = QImage::fromData(mydata, 0);

        QPainter Tochka;
        Tochka.begin(this);

        Tochka.translate(50, 50);

        Tochka.drawImage(0, 0, im, 0, 0, 720, 492);

        Tochka.end();
    }
}
// Рисование
void of::paintEvent(QPaintEvent *)
{
    MyDraw();
    this->update();
}
// Выход из программы
void of::MyExit()
{
    QApplication::quit();
}

* of2.rar (374.69 Кб - загружено 1017 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #41 : 22-05-2013 06:43 » 

zuze, начнём с того, что paintEvent даже в минимуме должен выглядеть так:

Код:
void of::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    //this->update(); -- это тут нельзя точно!!!
}

если ты вынес код рисования в MyDraw(), то ты должен передать туда ссылку на  painter, чтобы иметь возможность на нём рисовать

Код:
void of::MyDraw(QPainter& painter)
{
    
}


update() в отрисовке не вызывают, это может постоянным и бессмысленным вызовом paintEvent (но не рекурсией, к счастью, как было бы в случае repaint () )

зачем ты грузишь из файла во время каждой перерисовки ? Инициализируй объект QImage один раз, потом пользуйся

переформатирование - интерпретируешь массив байтов как массив структур пикселов, затем приводишь каждый пиксел в нужный вид

Добавлено через 2 минуты и 33 секунды:
а кодировку я себе обычно ставлю "UTF-8"  (соответственно, все файлы h и cpp тоже нужно держать в этой кодировке). Не возникает проблем ни с линуксом, ни с виндой , если придётся под обе системы прект компилить
« Последнее редактирование: 22-05-2013 06:46 от Алексей++ » Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #42 : 22-05-2013 10:17 » 

Алексей++, убрал this->update(), сделал открытие и чтение файла один раз. Изменил кодировку, так как в будущем с Linux предстоит работать.
Попытался сделать переформатирование, но выскочила ошибка.
Код основной программы и ошибка:

Код:
#include "of.h"
#include "ui_of.h"

#include <io.h>
#include <QByteArray>
#include <QFile>

#include <QPainter>
#include <QImage>

#include <QDebug>

QImage im(720, 492, QImage::Format_ARGB32);
QByteArray b;
struct QByteArray bstruct[492][720];
int k = 0;

of::of(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::of)
{
    ui->setupUi(this);

    // Для кодировки русского языка на виджетах
    QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale()); // Без этого кодировки БД не работает
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));  // ("CP-1251"));

    b = MyOpenReadFile();

    // Выход программы
    connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(MyExit()));
}
of::~of()
{
    delete ui;
}
// Рисование
void of::MyDraw()
{
   // здесь переформатирование
   for (int j = 0; j < 720; j++)
   {
       for (int i = 491; i >= 0; i--)
       {

           bstruct[i][j] = b[k];
           k++;
       }
   }

   im = QImage::fromData(b, 0);

   QPainter Tochka;
   Tochka.begin(this);

   Tochka.translate(50, 50);

   Tochka.drawImage(0, 0, im, 0, 0, 720, 492);

   Tochka.end();
}
// Рисование
void of::paintEvent(QPaintEvent *)
{
    MyDraw();
}
// Выход из программы
void of::MyExit()
{
    QApplication::quit();
}

// Открытие и чтенеи файла
QByteArray of::MyOpenReadFile()
{
    chdir("file");
    QFile file("1.dat");

    if (file.open(file.ReadOnly))
    {
        QByteArray mydata = file.readAll();
        file.close();

        mydata.remove(0, 8);
        return mydata;
    }
}

Ошибка в строке "bstruct[i][j] = b[k];"

invalid conversion from 'char' to 'const char*'
initializing argument of 'QByteArray& QByteArray::operator=(const char*)'

Также прикрепляю проект.

* of3.rar (376.05 Кб - загружено 1003 раз.)
« Последнее редактирование: 22-05-2013 15:56 от Алексей++ » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #43 : 22-05-2013 15:37 » 

Offtopic:
Вы столько всего и с такой скоростью пишите, что удивительно, как вы сами не путаетесь в том, какую проблему решаете.
Поставлю в угол.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #44 : 22-05-2013 15:55 » 

Dimka, смотри ЛС )
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #45 : 22-05-2013 15:58 » 

zuze, опять какие-то волшебные цифры - откуда они у тебя вот так, цифрами, взяты ? ) А если картинка сменится ?

Вопрос: как выглядит результат без цикла
Цитата
 
Код:
// здесь переформатирование
   for (int j = 0; j < 720; j++)
   {
       for (int i = 491; i >= 0; i--)
       {

           bstruct[i][j] = b[k];
           k++;
       }
   }
?
« Последнее редактирование: 22-05-2013 19:37 от Вад » Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #46 : 23-05-2013 04:52 » 

zuze, опять какие-то волшебные цифры - откуда они у тебя вот так, цифрами, взяты ? ) А если картинка сменится ?


Ничего волшебного, каждая картинка берётся, только из файла имеет единый формат. Сначала первые 8 байт управляющие, а затем байты самой картинки. Само количество байт для картинки 492*720.
Первый байт после управляющих символов - это R = 1-й байт, G = 1-й байт, B = 1-й байт. Второй байт следующая точка в цветности RGB по такому же принципу.

Вопрос: как выглядит результат без цикла

Закомментировал:
Код:
for (int j = 0; j < 720; j++)
   {
       for (int i = 491; i >= 0; i--)
       {

           bstruct[i][j] = b[k];
           k++;
       }
   }

Но к сожалению, тоже ничего не рисуется.

Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #47 : 23-05-2013 05:39 » 

>>Но к сожалению, тоже ничего не рисуется.
и в отладчике ты видишь, что до этого места (до вывода картинки) дело вообще доходит, а сам объект не IsNull() ?

-------------

zuze, то есть формат пиксела у тебя такой

Код:
#pragma pack(push,1)
struct
{
  uint8_t R;
  uint8_t G;
  uint8_t B;
};
#pragma pack(pop)

?
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #48 : 23-05-2013 06:22 » 

>>Но к сожалению, тоже ничего не рисуется.
и в отладчике ты видишь, что до этого места (до вывода картинки) дело вообще доходит, а сам объект не IsNull() ?

Поставил точку останова на строчку "b = MyOpenReadFile();" в отладчике не отображаются значения. Но когда я после этой строчке написал строчку "qDebug() << b;", то вывелось всё до байта равного нуля и в символьном виде.
Когда я делал с двухмерным массивом то выводились все байты общем количеством 492*720 и в десятичном виде.
 
zuze, то есть формат пиксела у тебя такой

Код:
#pragma pack(push,1)
struct
{
  uint8_t R;
  uint8_t G;
  uint8_t B;
};
#pragma pack(pop)
?

Да формат такой. При использовании двухмерного массива этот формат надо было ещё в десятичный вид было приводить.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #49 : 23-05-2013 06:54 » 

тогда ещё вопрос:
>>Но к сожалению, тоже ничего не рисуется.
ничего - это как выглядит ? Улыбаюсь Скриншот хоть покажи

И ещё - а ты знаешь, в каком формате пикселы в файле ? Приложи его, этот файл, что ли уже
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #50 : 23-05-2013 07:12 » 

тогда ещё вопрос:
>>Но к сожалению, тоже ничего не рисуется.
ничего - это как выглядит ? Улыбаюсь Скриншот хоть покажи

Прикрепляю скриншот программы.

И ещё - а ты знаешь, в каком формате пикселы в файле ?

Конечно, в нём значения в шестнадцатеричном виде. Каждое из этих значений не меньше 00 и не больше FF. У этих значений такой диапазон значений, что бы удовлетворял модели цветности RGB.



* myprog.jpg (42.49 Кб - загружено 1020 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #51 : 23-05-2013 07:15 » 

1) то есть, фон формы закрасился белым цветом ? А без попыток вывода картинки он тоже белый ? Это важно знать, так как в первом случае выходит так, что пикселы интерпретируются как белые, а во втором вообще ничего не рисуется скорее всего

2) я про формат спросил - приведи структуру одного пиксела в твоём файле
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #52 : 23-05-2013 07:31 » 

1) то есть, фон формы закрасился белым цветом ? А без попыток вывода картинки он тоже белый ? Это важно знать, так как в первом случае выходит так, что пикселы интерпретируются как белые, а во втором вообще ничего не рисуется скорее всего

Окно всегда такое серое, даже без вывода картинки я даже делал окна чёрное, всё равно не было картинки.

2) я про формат спросил - приведи структуру одного пиксела в твоём файле

Она такая же, как Вы поняли:
 
Код:
struct
{
  uint8_t R;
  uint8_t G;
  uint8_t B;
};

Единственный нюанс тут, как я понял, что uint8_t - это unsigned char, а для указания цвета надо привести в десятичный вид, то есть, что то типа этого сделать int(uint8_t).
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #53 : 23-05-2013 07:42 » 

1) выходит, картинка просто не выводится вообще,

это у тебя где-то тут
Цитата
Tochka.drawImage(0, 0, im, 0, 0, 720, 492);

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

Код:
Tochka.drawImage(QRect(20,20,100,100), im);

2) ничего приводить не нужно, uint8_t  - это уже один байт без знака
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #54 : 23-05-2013 10:00 » 

Единственный нюанс тут, как я понял, что uint8_t - это unsigned char, а для указания цвета надо привести в десятичный вид, то есть, что то типа этого сделать int(uint8_t).

Как всё запущено. Жаль
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #55 : 24-05-2013 05:11 » 

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

Код:
Tochka.drawImage(QRect(20,20,100,100), im);

Ничего не получилось, я думаю надо сначала проверить значения хранимые в QByteArray.
Делаю так:

Код:
for (int i = 0; i < b.size(); i++)
        qDebug() << b.at(i);

А в итоге выводятся только два байта и выскакивает ошибка:
ASSERT: "i >= 0 && i < size()" in file ..\..\include/QtCore/../../src/corelib/tools/qstring.h, line 688
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.


В добавок выскакивает такое окно:
1. Название окна: Microsoft Visual C++ Runtime Library
2. Сообщение окна:
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
3. Кнопка: ОК

И это случается, когда натыкается на байт со значением [00].
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #56 : 24-05-2013 05:21 » 

zuze, у тебя im нерабочий.  А то, что ты пытаешься распечатать массив с байтами - тут понятно, что будет падать
qDebug()<< пытается интерпретировать байты QByteArray как печатные символы, отсюда и ошибка. Содержимое массива можно глянуть в окне отладчика, в списке переменных. Или уж сделай функцию распечатки дампа

прицепи проект снова, что ли
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #57 : 24-05-2013 06:40 » 

zuze, у тебя im нерабочий.  А то, что ты пытаешься распечатать массив с байтами - тут понятно, что будет падать
qDebug()<< пытается интерпретировать байты QByteArray как печатные символы, отсюда и ошибка. Содержимое массива можно глянуть в окне отладчика, в списке переменных. Или уж сделай функцию распечатки дампа

Я проверил размер переменной QByteArray, всё впорядке с размером, он равен размеру файла минус 8 управляющих байт.

прицепи проект снова, что ли

Прикрепляю.

* of4.rar (376.72 Кб - загружено 946 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #58 : 24-05-2013 06:50 » 

а файл 1.dat где ?
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #59 : 24-05-2013 06:54 » 

а файл 1.dat где ?

Он лежит в "of-build-desktop\file\".
Записан
Страниц: 1 [2] 3 4  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines