Russian Qt Forum
Октябрь 03, 2024, 09:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Обрезка изображения  (Прочитано 12121 раз)
alexey11111
Гость
« : Ноябрь 04, 2012, 21:49 »

Друзья, помогите еще разок)))
Сделал объект (не без помощи форума Подмигивающий) - потомок QGraphicsItem, который можно перемещать, вращать и изменять размеры. Объект представляет собой прямоугольник и нужен для того, чтобы выделять часть изображения и сохранять ее (обрезка изображения, короче говоря). Делаю так:
QPoint tl = mapToParent(boundingRect().topLeft()).toPoint();//Координаты верхнего левого угла объекта
QPoint br = mapToParent(boundingRect().bottomRight()).toPoint();//Координаты нижнего правого угла объекта
QRect rct(tl, br);
QImage img = photoImg.copy(rct);
MVNDW->PreviewImage->setPixmap(QPixmap::fromImage(img));

Все работает, но если выделяющий прямоугольник повернуть, то вырезанное изображение получается не так как хотелось - нужно, чтобы вырезалась область под ПОВЕРНУТЫМ прямоугольником. А в данном случае получается, что берется не повернутый, а обычный прямоугольник, но с другими координатами верхнего и нижнего угла. (см. картинку cropper.jpg)
Подскажите, как решить эту проблему с малой кровью, или придется пересчитывать все повороты?
Записан
mutineer
Гость
« Ответ #1 : Ноябрь 04, 2012, 21:59 »

Поверни всю конструкцию (изображение и прямоугольник) таким образом, чтобы стороны прямоугольника были параллельны сторонам окна. После этого вырежи
Записан
alexey11111
Гость
« Ответ #2 : Ноябрь 04, 2012, 22:18 »

Сделал так:
        QTransform myTransform;
        myTransform.rotate(_rotat);/поворот на угол _rotat     
        QImage rotated = photoImg.transformed(myTransform);//вращаем все изображение
        QPoint tl = mapToParent(boundingRect().topLeft()).toPoint();
        QPoint br = mapToParent(boundingRect().bottomRight()).toPoint();
        QRect rct(tl, br);
        QImage img = rotated.copy(rct);
        MVNDW->PreviewImage->setPixmap(QPixmap::fromImage(img));

        //Здесь вращаем сам прямоугольник
        setTransformOriginPoint(_height/2, _width/2);
        setRotation(_rotat);

Вроде что-то вращается, но все-равно не то получилось...
Записан
mutineer
Гость
« Ответ #3 : Ноябрь 04, 2012, 22:56 »

Изображение ты повернул, а как насчет прямоугольника? Его тоже надо повернуть на тот же угол и только потом вырезать.

Зачем ты поворачиваешь его уже после обрезки?

Ну и хотелось бы видеть в чем выражается это самое "не то"
Записан
alexey11111
Гость
« Ответ #4 : Ноябрь 04, 2012, 23:03 »

Вот пример "не того".
Попробовал вращать прямоугольник до обрезки - то же самое.
Записан
mutineer
Гость
« Ответ #5 : Ноябрь 04, 2012, 23:06 »

Как видишь обрезка получилась уже под углом, но повернутая не в ту сторону. Значит изображение нужно повернуть в другую сторону. Почему координаты неправильные получились не знаю, возможно ты вращаешь изображение и прямоугольник вокруг разных точек. Лучше всего попробуй отобразить на экране результаты вращения
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Ноябрь 05, 2012, 13:22 »

аттач
Записан
alexey11111
Гость
« Ответ #7 : Ноябрь 05, 2012, 18:18 »

аттач

То, что надо!!! Миллион благодарностей Веселый
Записан
alexey11111
Гость
« Ответ #8 : Ноябрь 05, 2012, 20:42 »

аттач

То, что надо!!! Миллион благодарностей Веселый

Немного покрутил - работает опять не так как надо(
Вставил код из аттача в проект, получилось следующее:
Код:
void Cropper::wheelEvent(QGraphicsSceneWheelEvent *event)
{
        event->setAccepted( true );
        //qDebug()<<"X: "<<tl.x()<<" Y: "<<tl.y()<<" botX: "<<br.x()<<" botY: "<<br.y();

        int numDegrees = event->delta() / 8;
        int numSteps = numDegrees / 15;
        _rotat += numSteps;
        if(_rotat>90) _rotat=90;
        else if(_rotat<-90) _rotat=-90;

        QTransform trans = QTransform().rotate(-_rotat );

        qreal w = MVNDW->photoImg.width();
        qreal h = MVNDW->photoImg.height();

        QPointF p[4];
        p[0] = QPoint(0, 0);
        p[1] = QPointF(w, 0);
        p[2] = QPointF(w, h);
        p[3] = QPointF(0, h);

        QPointF offs(0, 0);
        for (int i = 0; i < 4; ++i)
        {
            QPointF temp = trans.map(p[i]);
            offs.setX(qMin(offs.x(), temp.x()));
            offs.setY(qMin(offs.y(), temp.y()));
        }


        QPointF LT = mapMapToPar[img][/img]ent(boundingRect().topLeft()) - offs;
        int x = int(LT.x());
        int y = int(LT.y() );

        QImage rotated = MVNDW->photoImg.transformed(trans).copy(x, y,         boundingRect().width(), boundingRect().height());
        MVNDW->PreviewImage->setPixmap(QPixmap::fromImage(rotated));
     
     

        setRotation(_rotat);

}

Однако если вращать, то получается следующее (картинка).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Ноябрь 05, 2012, 20:57 »

Код:
        QPointF LT = mapMapToPar[img][/img]ent(boundingRect().topLeft()) - offs;
Уточните эту строку. У меня все по-народному, в координатах имеджа. (0, 0) верхний левый угол. Привлекать др. трансформы нельзя
Записан
alexey11111
Гость
« Ответ #10 : Ноябрь 05, 2012, 21:06 »

Igors,
В твоем примере куда бы мы не поместили прямоугольник всегда все правильно вырезается. Строчка QPointF LT = trans.map(boundingRect().topLeft()) - offs у тебя работает корректно. В моем же случае, если я оставлю эту строчку в этом же виде, то получаю такую штуку (картинка). Т.е. куда бы не перемещался выделитель, координата его левого правого угла всегда будет началом координат QGraphicsScene (где расположена картинка). Поэтому я сделал:
QPointF LT = mapToParent(boundingRect().topLeft()) - offs
но легче не стало. Не понятно как правильно выбирать центр вращения в относительных координатах (что куда проецировать).
Записан
alexey11111
Гость
« Ответ #11 : Ноябрь 05, 2012, 21:26 »

Короче говоря, получается так.
Если я оставляю строчку  QPointF LT = trans.map(boundingRect().topLeft()) - offs;
то все обрезается корректно, если прямоугольник находится в точке (0,0) в координатах QGraphicsScene. Если же я его мышкой передвину в другое место и начинаю вращать, то он как будто бы остался на месте.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Ноябрь 05, 2012, 21:27 »

Поэтому я сделал:
QPointF LT = mapToParent(boundingRect().topLeft()) - offs
Ну Вы же boundingRect задавали в каких-то координатах (не знаю в каких). Вот в тех же координатах найдите верхний левый угол картинки и отнимите его oт topLeft - вот и получите нужную точку. По-любому Вам надо соскочить в систему координат имеджа, т.к. вырезка из него. Или подгоните проект - быстрее дело будет  
Записан
alexey11111
Гость
« Ответ #13 : Ноябрь 05, 2012, 21:41 »

В аттаче проект.
В коде много всякого хлама - не обращайте внимания. Класс signaller вообще не задействован. См. на класс Cropper. Вращение происходит колесиком - переопределен wheelEvent - при наведении мышки на квадрат. Если курсор вне квадрата, то ctrl+колесик - zoom (wheelEvent в классе photocontainer).
После запуска приложения выберите в поле sourcefolder папку, где есть файлы с изображениями (желательно, чтобы файлов других типов там не было).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Ноябрь 05, 2012, 23:27 »

Для того как у Вас написано перевод такой
QPointF LT = mapToScene(QPointF(_drawingOrigenX, _drawingOrigenY)) - offs;
Код
C++ (Qt)
QPointF LT = trans.map(mapToScene(QPointF(_drawingOrigenX, _drawingOrigenY))) - offs;
 
« Последнее редактирование: Ноябрь 06, 2012, 00:36 от Igors » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.395 секунд. Запросов: 23.