mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
[img-editor] Locked crop frame as stencil and clipped output by shape.
This commit is contained in:
@@ -475,6 +475,7 @@ void OpenPhotoEditorForSticker(
|
||||
.exactSize = QSize(kStickerSide, kStickerSide),
|
||||
.cropType = Editor::EditorData::CropType::RoundedRect,
|
||||
.keepAspectRatio = true,
|
||||
.fixedCrop = true,
|
||||
});
|
||||
const auto raw = editor.get();
|
||||
|
||||
|
||||
@@ -177,6 +177,10 @@ void Crop::paintFrame(QPainter &p) {
|
||||
p.save();
|
||||
p.setRenderHint(QPainter::Antialiasing, true);
|
||||
p.fillPath(frameShape, st::photoCropPointFg);
|
||||
if (_data.fixedCrop) {
|
||||
p.restore();
|
||||
return;
|
||||
}
|
||||
{
|
||||
const auto cornerLength = std::min(
|
||||
float64(st::photoEditorCropPointSize * 2),
|
||||
@@ -286,6 +290,10 @@ void Crop::convertCropPaintToOriginal() {
|
||||
}
|
||||
|
||||
void Crop::updateEdges() {
|
||||
if (_data.fixedCrop) {
|
||||
_edges.clear();
|
||||
return;
|
||||
}
|
||||
const auto &s = _pointSize;
|
||||
const auto &m = _edgePointMargins;
|
||||
const auto &r = _cropPaint;
|
||||
@@ -338,6 +346,9 @@ Qt::Edges Crop::mouseState(const QPoint &p) {
|
||||
}
|
||||
|
||||
void Crop::mousePressEvent(QMouseEvent *e) {
|
||||
if (_data.fixedCrop) {
|
||||
return;
|
||||
}
|
||||
computeDownState(e->pos());
|
||||
if (_down.edge) {
|
||||
setGridVisible(true, false);
|
||||
@@ -345,6 +356,9 @@ void Crop::mousePressEvent(QMouseEvent *e) {
|
||||
}
|
||||
|
||||
void Crop::mouseReleaseEvent(QMouseEvent *e) {
|
||||
if (_data.fixedCrop) {
|
||||
return;
|
||||
}
|
||||
const auto hadEdge = bool(_down.edge);
|
||||
if (hadEdge) {
|
||||
setGridVisible(false, true);
|
||||
@@ -474,6 +488,9 @@ void Crop::performMove(const QPoint &pos) {
|
||||
}
|
||||
|
||||
void Crop::mouseMoveEvent(QMouseEvent *e) {
|
||||
if (_data.fixedCrop) {
|
||||
return;
|
||||
}
|
||||
const auto pos = e->pos();
|
||||
const auto pressedEdge = _down.edge;
|
||||
|
||||
|
||||
@@ -237,6 +237,7 @@ PhotoEditor::PhotoEditor(
|
||||
std::move(show),
|
||||
_brushes,
|
||||
_brushTool)) {
|
||||
_modifications.cropType = data.cropType;
|
||||
|
||||
sizeValue(
|
||||
) | rpl::on_next([=](const QSize &size) {
|
||||
|
||||
@@ -9,8 +9,40 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "editor/scene/scene.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/userpic_view.h"
|
||||
|
||||
namespace Editor {
|
||||
namespace {
|
||||
|
||||
void ApplyShapeMask(QImage &image, EditorData::CropType type) {
|
||||
if (type == EditorData::CropType::Rect) {
|
||||
return;
|
||||
}
|
||||
if (image.format() != QImage::Format_ARGB32_Premultiplied) {
|
||||
image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
auto mask = QImage(image.size(), QImage::Format_ARGB32_Premultiplied);
|
||||
mask.fill(Qt::transparent);
|
||||
{
|
||||
auto p = QPainter(&mask);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(Qt::white);
|
||||
const auto rect = QRectF(QPointF(), QSizeF(image.size()));
|
||||
if (type == EditorData::CropType::Ellipse) {
|
||||
p.drawEllipse(rect);
|
||||
} else {
|
||||
const auto radius = std::min(rect.width(), rect.height())
|
||||
* Ui::ForumUserpicRadiusMultiplier();
|
||||
p.drawRoundedRect(rect, radius, radius);
|
||||
}
|
||||
}
|
||||
auto p = QPainter(&image);
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
p.drawImage(0, 0, mask);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
QImage ImageModified(QImage image, const PhotoModifications &mods) {
|
||||
Expects(!image.isNull());
|
||||
@@ -32,6 +64,7 @@ QImage ImageModified(QImage image, const PhotoModifications &mods) {
|
||||
auto cropped = mods.crop.isValid()
|
||||
? image.copy(mods.crop)
|
||||
: image;
|
||||
ApplyShapeMask(cropped, mods.cropType);
|
||||
QTransform transform;
|
||||
if (mods.flipped) {
|
||||
transform.scale(-1, 1);
|
||||
@@ -43,7 +76,11 @@ QImage ImageModified(QImage image, const PhotoModifications &mods) {
|
||||
}
|
||||
|
||||
bool PhotoModifications::empty() const {
|
||||
return !angle && !flipped && !crop.isValid() && !paint;
|
||||
return !angle
|
||||
&& !flipped
|
||||
&& !crop.isValid()
|
||||
&& cropType == EditorData::CropType::Rect
|
||||
&& !paint;
|
||||
}
|
||||
|
||||
PhotoModifications::operator bool() const {
|
||||
|
||||
@@ -11,18 +11,6 @@ namespace Editor {
|
||||
|
||||
class Scene;
|
||||
|
||||
struct PhotoModifications {
|
||||
int angle = 0;
|
||||
bool flipped = false;
|
||||
QRect crop;
|
||||
std::shared_ptr<Scene> paint = nullptr;
|
||||
|
||||
[[nodiscard]] bool empty() const;
|
||||
[[nodiscard]] explicit operator bool() const;
|
||||
~PhotoModifications();
|
||||
|
||||
};
|
||||
|
||||
struct EditorData {
|
||||
enum class CropType {
|
||||
Rect,
|
||||
@@ -35,6 +23,20 @@ struct EditorData {
|
||||
QSize exactSize;
|
||||
CropType cropType = CropType::Rect;
|
||||
bool keepAspectRatio = false;
|
||||
bool fixedCrop = false;
|
||||
};
|
||||
|
||||
struct PhotoModifications {
|
||||
int angle = 0;
|
||||
bool flipped = false;
|
||||
QRect crop;
|
||||
EditorData::CropType cropType = EditorData::CropType::Rect;
|
||||
std::shared_ptr<Scene> paint = nullptr;
|
||||
|
||||
[[nodiscard]] bool empty() const;
|
||||
[[nodiscard]] explicit operator bool() const;
|
||||
~PhotoModifications();
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]] QImage ImageModified(
|
||||
|
||||
Reference in New Issue
Block a user