Bugfixes and GIF uploads workinggit add -A!

This commit is contained in:
Zach Fox 2016-11-15 16:26:43 -08:00
parent 2c0cfdf241
commit 20a2d1275a
6 changed files with 57 additions and 44 deletions

View file

@ -5440,7 +5440,14 @@ void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRa
// Get a screenshot and save it // Get a screenshot and save it
QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio)); QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio));
SnapshotAnimated::saveSnapshotAnimated(includeAnimated, path, aspectRatio, qApp, DependencyManager::get<WindowScriptingInterface>()); // If we're not doing an animated snapshot as well...
if (!includeAnimated) {
// Tell the dependency manager that the capture of the still snapshot has taken place.
emit DependencyManager::get<WindowScriptingInterface>()->snapshotTaken(path, "", notify);
} else {
// Get an animated GIF snapshot and save it
SnapshotAnimated::saveSnapshotAnimated(path, aspectRatio, qApp, DependencyManager::get<WindowScriptingInterface>());
}
}); });
} }
void Application::shareSnapshot(const QString& path) { void Application::shareSnapshot(const QString& path) {

View file

@ -51,6 +51,9 @@ SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) {
return NULL; return NULL;
} }
QUrl url;
if (snapshotPath.right(3) == "jpg") {
QImage shot(snapshotPath); QImage shot(snapshotPath);
// no location data stored // no location data stored
@ -59,7 +62,12 @@ SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) {
} }
// parsing URL // parsing URL
QUrl url = QUrl(shot.text(URL), QUrl::ParsingMode::StrictMode); url = QUrl(shot.text(URL), QUrl::ParsingMode::StrictMode);
} else if (snapshotPath.right(3) == "gif") {
url = QUrl(DependencyManager::get<AddressManager>()->currentShareableAddress());
} else {
return NULL;
}
SnapshotMetaData* data = new SnapshotMetaData(); SnapshotMetaData* data = new SnapshotMetaData();
data->setURL(url); data->setURL(url);
@ -156,7 +164,11 @@ void Snapshot::uploadSnapshot(const QString& filename) {
file->open(QIODevice::ReadOnly); file->open(QIODevice::ReadOnly);
QHttpPart imagePart; QHttpPart imagePart;
if (filename.right(3) == "gif") {
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/gif"));
} else {
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
}
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, imagePart.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant("form-data; name=\"image\"; filename=\"" + file->fileName() + "\"")); QVariant("form-data; name=\"image\"; filename=\"" + file->fileName() + "\""));
imagePart.setBodyDevice(file); imagePart.setBodyDevice(file);

View file

@ -25,10 +25,9 @@ bool SnapshotAnimated::snapshotAnimatedTimerRunning = false;
QString SnapshotAnimated::snapshotAnimatedPath; QString SnapshotAnimated::snapshotAnimatedPath;
QString SnapshotAnimated::snapshotStillPath; QString SnapshotAnimated::snapshotStillPath;
void SnapshotAnimated::saveSnapshotAnimated(bool includeAnimated, QString pathStill, float aspectRatio, Application* app, QSharedPointer<WindowScriptingInterface> dm) { void SnapshotAnimated::saveSnapshotAnimated(QString pathStill, float aspectRatio, Application* app, QSharedPointer<WindowScriptingInterface> dm) {
// If we're not in the middle of capturing an animated snapshot... // If we're not in the middle of capturing an animated snapshot...
if ((SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp == 0) && (includeAnimated)) if (SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp == 0) {
{
// Define the output location of the still and animated snapshots. // Define the output location of the still and animated snapshots.
SnapshotAnimated::snapshotStillPath = pathStill; SnapshotAnimated::snapshotStillPath = pathStill;
SnapshotAnimated::snapshotAnimatedPath = pathStill; SnapshotAnimated::snapshotAnimatedPath = pathStill;
@ -41,33 +40,15 @@ void SnapshotAnimated::saveSnapshotAnimated(bool includeAnimated, QString pathSt
// Connect the snapshotAnimatedTimer QTimer to the lambda slot function // Connect the snapshotAnimatedTimer QTimer to the lambda slot function
QObject::connect(&(SnapshotAnimated::snapshotAnimatedTimer), &QTimer::timeout, [=] { QObject::connect(&(SnapshotAnimated::snapshotAnimatedTimer), &QTimer::timeout, [=] {
if (SnapshotAnimated::snapshotAnimatedTimerRunning) if (SnapshotAnimated::snapshotAnimatedTimerRunning) {
{
// Get a screenshot from the display, then scale the screenshot down, // Get a screenshot from the display, then scale the screenshot down,
// then convert it to the image format the GIF library needs, // then convert it to the image format the GIF library needs,
// then save all that to the QImage named "frame" // then save all that to the QImage named "frame"
QImage frame(app->getActiveDisplayPlugin()->getScreenshot(aspectRatio)); QImage frame(app->getActiveDisplayPlugin()->getScreenshot(aspectRatio));
frame = frame.scaledToWidth(SNAPSNOT_ANIMATED_WIDTH); frame = frame.scaledToWidth(SNAPSNOT_ANIMATED_WIDTH).convertToFormat(QImage::Format_RGBA8888);
frame = frame.convertToFormat(QImage::Format_RGBA8888);
// If this is the first frame... // If this is an intermediate or the final frame...
if (SnapshotAnimated::snapshotAnimatedTimestamp == 0) if (SnapshotAnimated::snapshotAnimatedTimestamp > 0) {
{
// Write out the header and beginning of the GIF file
GifBegin(&(SnapshotAnimated::snapshotAnimatedGifWriter), qPrintable(SnapshotAnimated::snapshotAnimatedPath), frame.width(), frame.height(), SNAPSNOT_ANIMATED_FRAME_DELAY_MSEC / 10);
// Write the first to the gif
GifWriteFrame(&(SnapshotAnimated::snapshotAnimatedGifWriter),
(uint8_t*)frame.bits(),
frame.width(),
frame.height(),
SNAPSNOT_ANIMATED_FRAME_DELAY_MSEC / 10);
// Record the current frame timestamp
SnapshotAnimated::snapshotAnimatedTimestamp = QDateTime::currentMSecsSinceEpoch();
SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp = SnapshotAnimated::snapshotAnimatedTimestamp;
}
// If that was an intermediate or the final frame...
else
{
// Variable used to determine how long the current frame took to pack // Variable used to determine how long the current frame took to pack
qint64 framePackStartTime = QDateTime::currentMSecsSinceEpoch(); qint64 framePackStartTime = QDateTime::currentMSecsSinceEpoch();
// Write the frame to the gif // Write the frame to the gif
@ -75,14 +56,13 @@ void SnapshotAnimated::saveSnapshotAnimated(bool includeAnimated, QString pathSt
(uint8_t*)frame.bits(), (uint8_t*)frame.bits(),
frame.width(), frame.width(),
frame.height(), frame.height(),
round(((float)(QDateTime::currentMSecsSinceEpoch() - SnapshotAnimated::snapshotAnimatedTimestamp + SnapshotAnimated::snapshotAnimatedLastWriteFrameDuration)) / 10)); round(((float)(framePackStartTime - SnapshotAnimated::snapshotAnimatedTimestamp + SnapshotAnimated::snapshotAnimatedLastWriteFrameDuration)) / 10));
// Record how long it took for the current frame to pack
SnapshotAnimated::snapshotAnimatedLastWriteFrameDuration = QDateTime::currentMSecsSinceEpoch() - framePackStartTime;
// Record the current frame timestamp // Record the current frame timestamp
SnapshotAnimated::snapshotAnimatedTimestamp = QDateTime::currentMSecsSinceEpoch(); SnapshotAnimated::snapshotAnimatedTimestamp = QDateTime::currentMSecsSinceEpoch();
// Record how long it took for the current frame to pack
SnapshotAnimated::snapshotAnimatedLastWriteFrameDuration = SnapshotAnimated::snapshotAnimatedTimestamp - framePackStartTime;
// If that was the last frame... // If that was the last frame...
if ((SnapshotAnimated::snapshotAnimatedTimestamp - SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp) >= (SNAPSNOT_ANIMATED_DURATION_SECS * 1000)) if ((SnapshotAnimated::snapshotAnimatedTimestamp - SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp) >= (SNAPSNOT_ANIMATED_DURATION_MSEC)) {
{
// Stop the snapshot QTimer. This action by itself DOES NOT GUARANTEE // Stop the snapshot QTimer. This action by itself DOES NOT GUARANTEE
// that the slot will not be called again in the future. // that the slot will not be called again in the future.
// See: http://lists.qt-project.org/pipermail/qt-interest-old/2009-October/013926.html // See: http://lists.qt-project.org/pipermail/qt-interest-old/2009-October/013926.html
@ -96,6 +76,19 @@ void SnapshotAnimated::saveSnapshotAnimated(bool includeAnimated, QString pathSt
// Let the dependency manager know that the snapshots have been taken. // Let the dependency manager know that the snapshots have been taken.
emit dm->snapshotTaken(SnapshotAnimated::snapshotStillPath, SnapshotAnimated::snapshotAnimatedPath, false); emit dm->snapshotTaken(SnapshotAnimated::snapshotStillPath, SnapshotAnimated::snapshotAnimatedPath, false);
} }
// If that was the first frame...
} else {
// Write out the header and beginning of the GIF file
GifBegin(&(SnapshotAnimated::snapshotAnimatedGifWriter), qPrintable(SnapshotAnimated::snapshotAnimatedPath), frame.width(), frame.height(), SNAPSNOT_ANIMATED_FRAME_DELAY_MSEC / 10);
// Write the first to the gif
GifWriteFrame(&(SnapshotAnimated::snapshotAnimatedGifWriter),
(uint8_t*)frame.bits(),
frame.width(),
frame.height(),
SNAPSNOT_ANIMATED_FRAME_DELAY_MSEC / 10);
// Record the current frame timestamp
SnapshotAnimated::snapshotAnimatedTimestamp = QDateTime::currentMSecsSinceEpoch();
SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp = SnapshotAnimated::snapshotAnimatedTimestamp;
} }
} }
}); });
@ -103,10 +96,8 @@ void SnapshotAnimated::saveSnapshotAnimated(bool includeAnimated, QString pathSt
// Start the snapshotAnimatedTimer QTimer - argument for this is in milliseconds // Start the snapshotAnimatedTimer QTimer - argument for this is in milliseconds
SnapshotAnimated::snapshotAnimatedTimer.start(SNAPSNOT_ANIMATED_FRAME_DELAY_MSEC); SnapshotAnimated::snapshotAnimatedTimer.start(SNAPSNOT_ANIMATED_FRAME_DELAY_MSEC);
SnapshotAnimated::snapshotAnimatedTimerRunning = true; SnapshotAnimated::snapshotAnimatedTimerRunning = true;
}
// If we're already in the middle of capturing an animated snapshot... // If we're already in the middle of capturing an animated snapshot...
else } else {
{
// Just tell the dependency manager that the capture of the still snapshot has taken place. // Just tell the dependency manager that the capture of the still snapshot has taken place.
emit dm->snapshotTaken(pathStill, "", false); emit dm->snapshotTaken(pathStill, "", false);
} }

View file

@ -24,6 +24,7 @@
// This value should divide evenly into 100. Snapshot framerate is NOT guaranteed. // This value should divide evenly into 100. Snapshot framerate is NOT guaranteed.
#define SNAPSNOT_ANIMATED_TARGET_FRAMERATE (25) #define SNAPSNOT_ANIMATED_TARGET_FRAMERATE (25)
#define SNAPSNOT_ANIMATED_DURATION_SECS (3) #define SNAPSNOT_ANIMATED_DURATION_SECS (3)
#define SNAPSNOT_ANIMATED_DURATION_MSEC (SNAPSNOT_ANIMATED_DURATION_SECS*1000)
#define SNAPSNOT_ANIMATED_FRAME_DELAY_MSEC (1000/SNAPSNOT_ANIMATED_TARGET_FRAMERATE) #define SNAPSNOT_ANIMATED_FRAME_DELAY_MSEC (1000/SNAPSNOT_ANIMATED_TARGET_FRAMERATE)
// This is the fudge factor that we add to the *first* GIF frame's "delay" value // This is the fudge factor that we add to the *first* GIF frame's "delay" value
@ -41,7 +42,7 @@ private:
static QString snapshotAnimatedPath; static QString snapshotAnimatedPath;
static QString snapshotStillPath; static QString snapshotStillPath;
public: public:
static void saveSnapshotAnimated(bool includeAnimated, QString pathStill, float aspectRatio, Application* app, QSharedPointer<WindowScriptingInterface> dm); static void saveSnapshotAnimated(QString pathStill, float aspectRatio, Application* app, QSharedPointer<WindowScriptingInterface> dm);
}; };
#endif // hifi_SnapshotAnimated_h #endif // hifi_SnapshotAnimated_h

View file

@ -23,17 +23,19 @@ function addImage(data) {
function toggle() { data.share = input.checked; } function toggle() { data.share = input.checked; }
img.src = data.localPath; img.src = data.localPath;
div.appendChild(img); div.appendChild(img);
data.share = true;
if (useCheckboxes) { // I'd rather use css, but the included stylesheet is quite particular. if (useCheckboxes) { // I'd rather use css, but the included stylesheet is quite particular.
// Our stylesheet(?) requires input.id to match label.for. Otherwise input doesn't display the check state. // Our stylesheet(?) requires input.id to match label.for. Otherwise input doesn't display the check state.
label.setAttribute('for', id); // cannot do label.for = label.setAttribute('for', id); // cannot do label.for =
input.id = id; input.id = id;
input.type = "checkbox"; input.type = "checkbox";
input.checked = (id === "p0"); input.checked = (id === "p0");
data.share = input.checked;
input.addEventListener('change', toggle); input.addEventListener('change', toggle);
div.class = "property checkbox"; div.class = "property checkbox";
div.appendChild(input); div.appendChild(input);
div.appendChild(label); div.appendChild(label);
} else {
data.share = true;
} }
document.getElementById("snapshot-images").appendChild(div); document.getElementById("snapshot-images").appendChild(div);
paths.push(data); paths.push(data);

View file

@ -36,7 +36,7 @@ var SNAPSHOT_REVIEW_URL = Script.resolvePath("html/SnapshotReview.html");
var outstanding; var outstanding;
function confirmShare(data) { function confirmShare(data) {
var dialog = new OverlayWebWindow('Snapshot Review', SNAPSHOT_REVIEW_URL, 800, 320); var dialog = new OverlayWebWindow('Snapshot Review', SNAPSHOT_REVIEW_URL, 800, 520);
function onMessage(message) { function onMessage(message) {
// Receives message from the html dialog via the qwebchannel EventBridge. This is complicated by the following: // Receives message from the html dialog via the qwebchannel EventBridge. This is complicated by the following:
// 1. Although we can send POJOs, we cannot receive a toplevel object. (Arrays of POJOs are fine, though.) // 1. Although we can send POJOs, we cannot receive a toplevel object. (Arrays of POJOs are fine, though.)