locked
Windows Store App - Saving Files And Sharing Problem

    Question

  • Hey Everyone 

     My goal is to implement the share charm. When the share delegate is called I have my canvas data saving to a temporary file, then I proceed with the share charm. I can successfully do this and share the image through the E-mail system. But for some reason if I try to share through OneNote, only the text goes through. Not the image. Something I noticed (which may be the problem) is that after I save out the canvas image, if I go and try to open the image in explorer it doesn't let me and says the file is in use for a good 5 minutes until finally it opens up.  Any ideas how to go about this problem? Any help is appreciated. Thanks all. 

    function shareImageHandler(e) {
            var request = e.request;
    
                var fileName;
                var canvasData;
                var Imaging = Windows.Graphics.Imaging;
                var tempFolder = Windows.Storage.ApplicationData.current.temporaryFolder;
    
                request.data.properties.title = "My Drawing";
                request.data.properties.description = "Share your drawings with others";
    
                var deferral = request.getDeferral();
                tempFolder.createFileAsync("MyWhiteboxImage.png", Windows.Storage.CreationCollisionOption.replaceExisting).then(function (file) {
                    if (file) {
                        // Prevent updates to the remote version of the file until we finish making changes and call CompleteUpdatesAsync.
                        Windows.Storage.CachedFileManager.deferUpdates(file);
                        fileName = file.displayName;
                        savedFile = file;
                        return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
                    }
                }).then(function (stream) {
                    //Create imageencoder object
                    if (stream) {
                        //Get the canvas data
                        canvasData = getMergedCanvas().getContext("2d").getImageData(0, 0, drawCanvas.width, drawCanvas.height);
                        return Imaging.BitmapEncoder.createAsync(Imaging.BitmapEncoder.pngEncoderId, stream);
                    }
                }).then(function (encoder) {
                    //Set the pixel data in the encoderaz
                    if (encoder) {
                        encoder.setPixelData(Imaging.BitmapPixelFormat.rgba8, Imaging.BitmapAlphaMode.straight,
                        drawCanvas.width, drawCanvas.height, 96, 96, new Uint8Array(canvasData.data));
    
                        //Go do the encoding
                        return encoder.flushAsync();
                    }
                }).then(function (e) {
                    Windows.Storage.CachedFileManager.completeUpdatesAsync(savedFile).then(function (e) {
                        var rStream = Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(savedFile);
                        request.data.properties.thumbnail = rStream;
                        request.data.setText("Here is my Whiteboard Creation");
                        request.data.setStorageItems([savedFile]);
                        request.data.setBitmap(rStream);
                        request.data.setUri(new Windows.Foundation.Uri(drawCanvas.toDataURL("image/bmp")));
                        deferral.complete();
                    });
                });
        }

    Wednesday, June 05, 2013 6:14 PM

Answers

  • Hi,

    Sharing images can be a bit tricky to some destinations, this is the code I use (working on a deployed App) to share a canvas as an image:

    var output;
    var input;
    var outputStream;
    var blob = document.querySelector("#myCanvas").msToBlob();
    var deferral = e.request.getDeferral();
                    Windows.Storage.ApplicationData.current.temporaryFolder.createFileAsync("temporaryImage.png",
                              Windows.Storage.CreationCollisionOption.replaceExisting).
                        then(function (file) {
                            return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
                        }).then(function (stream) {
                            outputStream = stream;
                            output = stream.getOutputStreamAt(0);
                            input = blob.msDetachStream();
                            return Windows.Storage.Streams.RandomAccessStream.copyAsync(input, output);
                        }).then(function () {
                            return output.flushAsync();
                        }).done(function () {
                            input.close();
                            output.close();
                            outputStream.close();
                            Windows.Storage.ApplicationData.current.temporaryFolder.getFileAsync("temporaryImage.png").done(function (imageFile) {
                                request.data.properties.title = "Some title";
                                request.data.properties.description = "a description";
                                var streamReference = Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(imageFile);
                                request.data.properties.thumbnail = streamReference;
                                request.data.setStorageItems([imageFile]);
                                request.data.setBitmap(streamReference);
                                deferral.complete();
                            });
    
                        });

    Some destinations read the "thumbnail" property while others use the StorageItem.

    The problem with the file not being readable could be because you are not closing the Streams correctly.

    Friday, June 07, 2013 5:04 PM

All replies

  • Hi,

    Sharing images can be a bit tricky to some destinations, this is the code I use (working on a deployed App) to share a canvas as an image:

    var output;
    var input;
    var outputStream;
    var blob = document.querySelector("#myCanvas").msToBlob();
    var deferral = e.request.getDeferral();
                    Windows.Storage.ApplicationData.current.temporaryFolder.createFileAsync("temporaryImage.png",
                              Windows.Storage.CreationCollisionOption.replaceExisting).
                        then(function (file) {
                            return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
                        }).then(function (stream) {
                            outputStream = stream;
                            output = stream.getOutputStreamAt(0);
                            input = blob.msDetachStream();
                            return Windows.Storage.Streams.RandomAccessStream.copyAsync(input, output);
                        }).then(function () {
                            return output.flushAsync();
                        }).done(function () {
                            input.close();
                            output.close();
                            outputStream.close();
                            Windows.Storage.ApplicationData.current.temporaryFolder.getFileAsync("temporaryImage.png").done(function (imageFile) {
                                request.data.properties.title = "Some title";
                                request.data.properties.description = "a description";
                                var streamReference = Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(imageFile);
                                request.data.properties.thumbnail = streamReference;
                                request.data.setStorageItems([imageFile]);
                                request.data.setBitmap(streamReference);
                                deferral.complete();
                            });
    
                        });

    Some destinations read the "thumbnail" property while others use the StorageItem.

    The problem with the file not being readable could be because you are not closing the Streams correctly.

    Friday, June 07, 2013 5:04 PM
  • Thank you Easlur! I modified my code to match your system and it is working better. I believe it was the closing of the streams that I was missing. OneNote still isn't taking my image data but file saving is now working smoothly. 
    Wednesday, June 12, 2013 5:42 PM
  • Your welcome!

    The OneNote probleme could be related to some particular property  that OneNote needs on the "request.data.properties", sadly there is no document or site that I could find that explicitly says which property does OneNote require.

    Wednesday, June 12, 2013 6:06 PM