update
This commit is contained in:
@@ -2241,8 +2241,8 @@ bool ProjectWorkspace::resolveBlackholeByUseOriginalBackground(const QString& id
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProjectWorkspace::resolveBlackholeByCopyBackground(const QString& id, const QPoint& sourceOffsetPx,
|
||||
bool hideBlackholeAfterFill) {
|
||||
bool ProjectWorkspace::resolveBlackholeByCopyBackground(const QString& id, const QRect& targetWorldInBackground,
|
||||
const QRect& srcWorldInBackground, bool hideBlackholeAfterFill) {
|
||||
if (m_projectDir.isEmpty() || id.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
@@ -2267,68 +2267,67 @@ bool ProjectWorkspace::resolveBlackholeByCopyBackground(const QString& id, const
|
||||
return false;
|
||||
}
|
||||
|
||||
QImage bg = image_file::loadImageLimited(bgAbs, image_decode::kWorkspaceMaxPixels);
|
||||
if (bg.isNull()) {
|
||||
const QRect targetWorld = targetWorldInBackground.normalized();
|
||||
const QRect srcWorld = srcWorldInBackground.normalized();
|
||||
if (!targetWorld.isValid() || !srcWorld.isValid() || targetWorld.width() <= 0 || targetWorld.height() <= 0) {
|
||||
return false;
|
||||
}
|
||||
if (bg.format() != QImage::Format_ARGB32_Premultiplied) {
|
||||
bg = bg.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
if (targetWorld.width() != srcWorld.width() || targetWorld.height() != srcWorld.height()) {
|
||||
return false;
|
||||
}
|
||||
const QImage srcSnapshot = bg;
|
||||
|
||||
QSize logicalSz;
|
||||
if (!image_file::probeImagePixelSize(bgAbs, &logicalSz) || !logicalSz.isValid() || logicalSz.width() < 1 ||
|
||||
logicalSz.height() < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QPainterPath holePathWorld;
|
||||
holePathWorld.addPolygon(QPolygonF(ent.cutoutPolygonWorld));
|
||||
holePathWorld.closeSubpath();
|
||||
const QRect targetWorld =
|
||||
holePathWorld.boundingRect().toAlignedRect().intersected(QRect(0, 0, logicalSz.width(), logicalSz.height()));
|
||||
if (!targetWorld.isValid() || targetWorld.width() <= 0 || targetWorld.height() <= 0) {
|
||||
const QRect bounds(0, 0, logicalSz.width(), logicalSz.height());
|
||||
if (targetWorld.intersected(bounds) != targetWorld || srcWorld.intersected(bounds) != srcWorld) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QRect srcWorld(targetWorld.topLeft() + sourceOffsetPx, targetWorld.size());
|
||||
if (srcWorld.left() < 0) srcWorld.moveLeft(0);
|
||||
if (srcWorld.top() < 0) srcWorld.moveTop(0);
|
||||
if (srcWorld.right() >= logicalSz.width()) srcWorld.moveRight(logicalSz.width() - 1);
|
||||
if (srcWorld.bottom() >= logicalSz.height()) srcWorld.moveBottom(logicalSz.height() - 1);
|
||||
srcWorld = srcWorld.intersected(QRect(0, 0, logicalSz.width(), logicalSz.height()));
|
||||
if (srcWorld.width() != targetWorld.width() || srcWorld.height() != targetWorld.height()) {
|
||||
QImage targetPatch;
|
||||
QImage srcPatch;
|
||||
if (!image_file::loadRegionToQImageExact(bgAbs, targetWorld, &targetPatch) ||
|
||||
!image_file::loadRegionToQImageExact(bgAbs, srcWorld, &srcPatch) || targetPatch.isNull() ||
|
||||
srcPatch.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const qreal sx = bg.width() / qreal(logicalSz.width());
|
||||
const qreal sy = bg.height() / qreal(logicalSz.height());
|
||||
QTransform worldToBg;
|
||||
worldToBg.scale(sx, sy);
|
||||
|
||||
const QRect targetImg =
|
||||
worldToBg.mapRect(QRectF(targetWorld)).toAlignedRect().intersected(QRect(0, 0, bg.width(), bg.height()));
|
||||
const QRect srcImg =
|
||||
worldToBg.mapRect(QRectF(srcWorld)).toAlignedRect().intersected(QRect(0, 0, bg.width(), bg.height()));
|
||||
if (!targetImg.isValid() || !srcImg.isValid() || targetImg.width() != srcImg.width() ||
|
||||
targetImg.height() != srcImg.height()) {
|
||||
if (targetPatch.size() != srcPatch.size() || targetPatch.width() != targetWorld.width() ||
|
||||
targetPatch.height() != targetWorld.height()) {
|
||||
return false;
|
||||
}
|
||||
if (targetPatch.format() != QImage::Format_ARGB32_Premultiplied) {
|
||||
targetPatch = targetPatch.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
if (srcPatch.format() != QImage::Format_ARGB32_Premultiplied) {
|
||||
srcPatch = srcPatch.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
|
||||
const QPainterPath holePathImg = worldToBg.map(holePathWorld);
|
||||
QPolygonF polyLocal;
|
||||
polyLocal.reserve(ent.cutoutPolygonWorld.size());
|
||||
for (const QPointF& pt : ent.cutoutPolygonWorld) {
|
||||
polyLocal.append(pt - targetWorld.topLeft());
|
||||
}
|
||||
QPainterPath holePathLocal;
|
||||
if (polyLocal.size() >= 3) {
|
||||
holePathLocal.addPolygon(polyLocal);
|
||||
holePathLocal.closeSubpath();
|
||||
}
|
||||
|
||||
{
|
||||
QPainter p(&bg);
|
||||
QPainter p(&targetPatch);
|
||||
p.setRenderHint(QPainter::Antialiasing, true);
|
||||
p.setClipPath(holePathImg);
|
||||
p.drawImage(targetImg.topLeft(), srcSnapshot, srcImg);
|
||||
if (!holePathLocal.isEmpty()) {
|
||||
p.setClipPath(holePathLocal);
|
||||
}
|
||||
p.drawImage(0, 0, srcPatch);
|
||||
p.end();
|
||||
}
|
||||
|
||||
const QImage patch = bg.copy(targetImg);
|
||||
const auto before = m_project.entities();
|
||||
QString overlayRel;
|
||||
if (!writeBlackholeOverlayPng(m_projectDir, id, ents[hit].blackholeOverlayPath, patch, targetWorld,
|
||||
if (!writeBlackholeOverlayPng(m_projectDir, id, ents[hit].blackholeOverlayPath, targetPatch, targetWorld,
|
||||
&overlayRel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user