diff --git a/KShare.pro b/KShare.pro index 8f46910..1662f36 100644 --- a/KShare.pro +++ b/KShare.pro @@ -59,7 +59,9 @@ SOURCES += main.cpp\ recording/encoders/encodersettings.cpp \ recording/encoders/encodersettingsdialog.cpp \ settingsdialog.cpp \ - aboutbox.cpp + aboutbox.cpp \ + cropeditor/drawing/eraseritem.cpp \ + cropeditor/drawing/rectitem.cpp HEADERS += mainwindow.hpp \ cropeditor/cropeditor.hpp \ @@ -97,7 +99,9 @@ HEADERS += mainwindow.hpp \ recording/encoders/encodersettings.hpp \ recording/encoders/encodersettingsdialog.hpp \ settingsdialog.hpp \ - aboutbox.hpp + aboutbox.hpp \ + cropeditor/drawing/eraseritem.hpp \ + cropeditor/drawing/rectitem.hpp LIBS += -lavcodec -lavformat -lavutil -lswscale -lavutil diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index a7f46d9..986176e 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -8,8 +8,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -28,10 +30,22 @@ CropScene::CropScene(QObject *parent, QPixmap *pixmap) addDrawingAction(menu, "Blur", [] { return new BlurItem; }); addDrawingAction(menu, "Straight line", [] { return new LineItem; }); addDrawingAction(menu, "Text", [] { return new TextItem; }); + addDrawingAction(menu, "Rectangle", [] { return new RectItem; }); + + menu.addSeparator(); + addDrawingAction(menu, "Eraser", [] { return new EraserItem; }); QAction *reset = menu.addAction("Reset"); connect(reset, &QAction::triggered, [&] { setDrawingSelection("None", [] { return nullptr; }); }); + QAction *clear = menu.addAction("Clear all drwawing"); + connect(clear, &QAction::triggered, [&] { + auto its = items(); + for (auto i : its) { + if (i != rect && i != polyItem && i->zValue() != -1) removeItem(i); + } + }); + menu.addSeparator(); QAction *settings = new QAction; settings->setText("Settings"); diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp index 64703a3..eeb1d69 100644 --- a/cropeditor/cropscene.hpp +++ b/cropeditor/cropscene.hpp @@ -25,6 +25,12 @@ public: QPixmap *pixmap() { return _pixmap; } + QGraphicsPolygonItem *polyItm() { + return polyItem; + } + QGraphicsRectItem *selRect() { + return rect; + } public slots: void fontAsk(); diff --git a/cropeditor/drawing/eraseritem.cpp b/cropeditor/drawing/eraseritem.cpp new file mode 100644 index 0000000..0d3a53c --- /dev/null +++ b/cropeditor/drawing/eraseritem.cpp @@ -0,0 +1,16 @@ +#include "eraseritem.hpp" + +EraserItem::EraserItem() { +} + +EraserItem::~EraserItem() { +} + +void EraserItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { + for (auto i : scene->items()) { + if (i->contains(e->scenePos()) && i->zValue() != -1 && i != scene->polyItm() && i != scene->selRect()) { + scene->removeItem(i); + break; + } + } +} diff --git a/cropeditor/drawing/eraseritem.hpp b/cropeditor/drawing/eraseritem.hpp new file mode 100644 index 0000000..078cd2d --- /dev/null +++ b/cropeditor/drawing/eraseritem.hpp @@ -0,0 +1,18 @@ +#ifndef ERASERITEM_HPP +#define ERASERITEM_HPP + +#include "drawitem.hpp" + +class EraserItem : public DrawItem { +public: + EraserItem(); + ~EraserItem(); + QString name() override { + return "Eraser"; + } + void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) override; + void mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) override { + } +}; + +#endif // ERASERITEM_HPP diff --git a/cropeditor/drawing/rectitem.cpp b/cropeditor/drawing/rectitem.cpp new file mode 100644 index 0000000..5524661 --- /dev/null +++ b/cropeditor/drawing/rectitem.cpp @@ -0,0 +1,23 @@ +#include "rectitem.hpp" + +RectItem::RectItem() { +} + +RectItem::~RectItem() { +} + +void RectItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { + if (!rect) { + rect = scene->addRect(e->scenePos().x(), e->scenePos().y(), 0, 0); + rect->setBrush(scene->brush()); + rect->setPen(scene->pen()); + initPos = e->scenePos(); + } else { + auto p = e->scenePos(); + rect->setRect( + QRect(qMin(initPos.x(), p.x()), qMin(initPos.y(), p.y()), qAbs(initPos.x() - p.x()), qAbs(initPos.y() - p.y()))); + } +} + +void RectItem::mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) { +} diff --git a/cropeditor/drawing/rectitem.hpp b/cropeditor/drawing/rectitem.hpp new file mode 100644 index 0000000..8e09d80 --- /dev/null +++ b/cropeditor/drawing/rectitem.hpp @@ -0,0 +1,21 @@ +#ifndef RECTITEM_HPP +#define RECTITEM_HPP + +#include "drawitem.hpp" + +class RectItem : public DrawItem { +public: + RectItem(); + ~RectItem(); + QString name() override { + return "Rectangle"; + } + void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) override; + void mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) override; + +private: + QGraphicsRectItem *rect = nullptr; + QPointF initPos; +}; + +#endif // RECTITEM_HPP diff --git a/cropeditor/drawing/textitem.cpp b/cropeditor/drawing/textitem.cpp index 1c1a007..dd972fe 100644 --- a/cropeditor/drawing/textitem.cpp +++ b/cropeditor/drawing/textitem.cpp @@ -12,8 +12,8 @@ void TextItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) { if (!textItem) { textItem = scene->addSimpleText(text, scene->font()); textItem->setPos(e->scenePos()); - textItem->setPen(scene->pen()); - textItem->setBrush(scene->brush()); + textItem->setPen(scene->pen().color()); + textItem->setBrush(scene->pen().color()); } else { auto ee = 180 + qRadiansToDegrees(qAtan2((textItem->pos().y() - e->scenePos().y()), (textItem->pos().x() - e->scenePos().x()))); diff --git a/recording/encoders/encoder.cpp b/recording/encoders/encoder.cpp index d14f046..52bb31c 100644 --- a/recording/encoders/encoder.cpp +++ b/recording/encoders/encoder.cpp @@ -87,10 +87,11 @@ Encoder::Encoder(QString &targetFile, QSize res, CodecSettings *settings) { success = true; } -void Encoder::setFrameRGB(uint8_t *rgb) { +void Encoder::setFrameRGB(QImage img) { + uint8_t *rgb = (uint8_t *)img.bits(); int ret = av_frame_make_writable(out->frame); if (ret < 0) throwAVErr(ret, "setFrameRGB"); - int lineSize[1] = { 3 * out->enc->width }; + int lineSize[1] = { img.bytesPerLine() }; out->sws = sws_getCachedContext(out->sws, out->enc->width, out->enc->height, AV_PIX_FMT_RGB24, out->enc->width, out->enc->height, (AVPixelFormat)out->frame->format, 0, 0, 0, 0); sws_scale(out->sws, (const uint8_t *const *)&rgb, lineSize, 0, out->enc->height, out->frame->data, out->frame->linesize); @@ -105,8 +106,7 @@ bool Encoder::addFrame(QImage frm) { if (!success) return false; if (frm.size() != size) frm = frm.copy(QRect(QPoint(0, 0), size)); if (frm.format() != QImage::Format_RGB888) frm = frm.convertToFormat(QImage::Format_RGB888); - uint8_t *frameData = (uint8_t *)frm.bits(); - setFrameRGB(frameData); + setFrameRGB(frm); AVPacket pkt; pkt.size = 0; pkt.data = NULL; @@ -140,6 +140,8 @@ bool Encoder::isRunning() { } bool Encoder::end() { + if (ended) return false; + ended = true; if (!success) { goto cleanup; } diff --git a/recording/encoders/encoder.hpp b/recording/encoders/encoder.hpp index 2d0be81..6a5ca6c 100644 --- a/recording/encoders/encoder.hpp +++ b/recording/encoders/encoder.hpp @@ -45,10 +45,11 @@ private: AVFormatContext *fc = NULL; bool success = false; + bool ended = false; QSize size; - void setFrameRGB(uint8_t *rgb); + void setFrameRGB(QImage img); }; #endif // ENCODER_HPP diff --git a/recording/recordingformats.cpp b/recording/recordingformats.cpp index 115dcf1..2e449b6 100644 --- a/recording/recordingformats.cpp +++ b/recording/recordingformats.cpp @@ -30,6 +30,12 @@ RecordingFormats::RecordingFormats(formats::Recording f) { iFormat = QImage::Format_RGB888; path = tmpDir.absoluteFilePath("res." + formats::recordingFormatName(f).toLower()); finalizer = [&] { + qDebug() << "end"; + try { + enc->end(); + } catch (std::runtime_error e) { + qCritical() << "Encoder error: " << e.what(); + } delete enc; if (interrupt) { tmpDir.removeRecursively();