Take screenshot

View inC++QMLView on GitHubSample viewer app

Take a screenshot of the map.

screenshot

Use case

GIS users may want to export a screenshot of a map to enable sharing as an image or printing.

How to use the sample

Pan and zoom to find an interesting location. Press Take screenshot, and a screenshot image will display over the map. Note that there may be a small delay if the map is still rendering when you push the button.

How it works

  1. The exportImage function is executed on the MapView.
  2. Once the asynchronous task completes, a QImage is returned.
  3. QML cannot directly render a QImage. Instead, a QML Image Provider must be created for generating an in-memory URL to the returned QImage. This is done with the following steps:
  • Subclass QQuickImageProvider.
  • Reimplement the requestImage function.
  • Add an image provider to the QQmlEngine instance using QQmlEngine::addImageProvider.
  • Create a Q_PROPERTY that returns the image URL from the Image Provider.
  • Bind the QML Image to the image URL property. When this property changes, it will automatically trigger the requestImage function and return the URL to the image.

Relevant API

  • GeoView::exportImage

Tags

capture, export, image, print, screen capture, screenshot, share, shot

Sample Code

TakeScreenshot.cppTakeScreenshot.cppTakeScreenshot.hMapImageProvider.cppMapImageProvider.hTakeScreenshot.qml
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// [WriteFile Name=TakeScreenshot, Category=Maps]
// [Legal]
// Copyright 2018 Esri.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// [Legal]

#ifdef PCH_BUILD
#include "pch.hpp"
#endif // PCH_BUILD

#include "TakeScreenshot.h"

#include "Map.h"
#include "MapQuickView.h"
#include "MapImageProvider.h"
#include "MapTypes.h"

#include <QFuture>
#include <QQmlContext>
#include <QUuid>

using namespace Esri::ArcGISRuntime;

TakeScreenshot::TakeScreenshot(QQuickItem* parent /* = nullptr */):
  QQuickItem(parent)
{
}

void TakeScreenshot::init()
{
  // Register the map view for QML
  qmlRegisterType<MapQuickView>("Esri.Samples", 1, 0, "MapView");
  qmlRegisterType<TakeScreenshot>("Esri.Samples", 1, 0, "TakeScreenshotSample");
}

void TakeScreenshot::componentComplete()
{
  QQuickItem::componentComplete();

  // find QML MapView component
  m_mapView = findChild<MapQuickView*>("mapView");

  // Create a map using the imagery basemap
  m_map = new Map(BasemapStyle::ArcGISImageryStandard, this);

  // Set map to map view
  m_mapView->setMap(m_map);

  // Get the image provider from the QML Engine
  QQmlEngine* engine = QQmlEngine::contextForObject(this)->engine();
  m_imageProvider = dynamic_cast<MapImageProvider*>(engine->imageProvider(MapImageProvider::imageProviderId()));
}

// Q_INVOKABLE function to kick off the export image asynchronous task
void TakeScreenshot::captureScreenshot()
{
  m_mapView->exportImageAsync().then(this, [this](QImage img)
  {
    // convert the QUuid into a QString
    const QString imageId = QUuid().createUuid().toString(QUuid::WithoutBraces);
    // add the image to the provider
    m_imageProvider->addImage(imageId, img);
    // update the URL with the unique id
    m_mapImageUrl = QString("image://%1/%2").arg(MapImageProvider::imageProviderId(), imageId);
    // emit the signal to trigger the QML Image to update
    emit mapImageUrlChanged();
  });
}

QUrl TakeScreenshot::mapImageUrl() const
{
  return m_mapImageUrl;
}

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.