0
votes

when I take photo in my program and save it in Picturelibrary filewatcher is not working but when I copy and paste image in to Picturelibrary filewatcher is working in correctly. please help me solve my problem. sorry for my low skill

//camera preview

private async void BtnCamera_Click_1(object sender, RoutedEventArgs e) {

        DisplayRequest displayRequest = new DisplayRequest();
        Windows.Media.Capture.MediaCapture mediaCapture;
        mediaCapture = new MediaCapture();
        var cameraDevice = await FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel.Back);
        var settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };
        await mediaCapture.InitializeAsync(settings);
        displayRequest.RequestActive();
        PreviewControl.Source = mediaCapture;
        await mediaCapture.StartPreviewAsync();
        var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
        var storageFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
        BtnCamera.Visibility = (BtnCamera.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible);
        PauseBtn.Visibility = (PauseBtn.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible);
    }

//save picture

private async void BtnSave_Click(object sender, RoutedEventArgs e) {

        //var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
        var rtb = new RenderTargetBitmap();
        await rtb.RenderAsync(ImageHolder); // Render control to RenderTargetBitmap

        // Get pixels from RTB
        IBuffer pixelBuffer = await rtb.GetPixelsAsync();
        byte[] pixels = pixelBuffer.ToArray();

        // Support custom DPI
        DisplayInformation displayInformation = DisplayInformation.GetForCurrentView();
        var stream = new InMemoryRandomAccessStream();
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
        encoder.SetPixelData(BitmapPixelFormat.Bgra8, // RGB with alpha
                             BitmapAlphaMode.Premultiplied,
                             (uint)rtb.PixelWidth,
                             (uint)rtb.PixelHeight,
                             displayInformation.RawDpiX,
                             displayInformation.RawDpiY,
                             pixels);

        // Write data to the stream
        stream.Seek(0);
        await encoder.FlushAsync();
        using (var dataReader = new DataReader(stream.GetInputStreamAt(0)))
        {
            StorageFolder folder = KnownFolders.PicturesLibrary;
            StorageFile file = await folder.CreateFileAsync("snapshot" + DateTime.Now.ToString("MM-dd-yyyy ss.fff") + ".jpg", CreationCollisionOption.GenerateUniqueName);
            await dataReader.LoadAsync((uint)stream.Size);
            byte[] buffer = new byte[(int)stream.Size];
            dataReader.ReadBytes(buffer);
            await FileIO.WriteBytesAsync(file, buffer);
            //await file.CopyAsync(folder, "ProfilePhoto.jpg", NameCollisionOption.GenerateUniqueName);
            //await file.DeleteAsync();


        }

//fileWatcher

async void EnableChangeTracker() {

        StorageLibrary picsLib = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
        StorageLibraryChangeTracker picTracker = picsLib.ChangeTracker;
        picTracker.Enable();
        List<string> supportExtension = new List<string>();
        supportExtension.Add(".png");
        supportExtension.Add(".jpg");

        StorageFolder photos = KnownFolders.PicturesLibrary;
        // Create a query containing all the files your app will be tracking
        QueryOptions option = new QueryOptions(CommonFileQuery.DefaultQuery, supportExtension);
        option.FolderDepth = FolderDepth.Shallow;
        // This is important because you are going to use indexer for notifications
        option.IndexerOption = IndexerOption.UseIndexerWhenAvailable;
        StorageFileQueryResult resultSet = photos.CreateFileQueryWithOptions(option);
        // Indicate to the system the app is ready to change track
        await resultSet.GetFilesAsync();
        // Attach an event handler for when something changes on the system

        resultSet.ContentsChanged += Query_ContentsChangedAsync;
    }




 async void Query_ContentsChangedAsync(IStorageQueryResultBase sender, object args)
    {

    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
         {




             ImgList.Clear();
             GetFiles();



         });




    }
1

1 Answers

0
votes

There're two issues in your code.

  1. If you want to use MediaCapture to take photos and save it into picture library. You actually do not need to use DataReader and RenderTargetBitmap to do these extra operations. Just using BitmapEncoder and BitmapDecoder are enough. See the 'TakePhotoAsync' method in CameraManualControls sample. If you said that you have to use RenderTargetBitmap, then ignore this suggestion.
  2. When saving a new picture in the picture library, you still need to call await resultSet.GetFilesAsync() method everytime for firing the 'ContentsChanged' event.

So, the changed code looks like the following:

private StorageFileQueryResult resultSet;

private async Task EnableChangeTracker()
{
    StorageLibrary picsLib = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
    StorageLibraryChangeTracker picTracker = picsLib.ChangeTracker;
    picTracker.Enable();
    List<string> supportExtension = new List<string>();
    supportExtension.Add(".png");
    supportExtension.Add(".jpg");

    StorageFolder photos = KnownFolders.PicturesLibrary;
    // Create a query containing all the files your app will be tracking
    QueryOptions option = new QueryOptions(CommonFileQuery.DefaultQuery, supportExtension);
    option.FolderDepth = FolderDepth.Shallow;
    // This is important because you are going to use indexer for notifications
    option.IndexerOption = IndexerOption.UseIndexerWhenAvailable;
    resultSet = photos.CreateFileQueryWithOptions(option);
    // Indicate to the system the app is ready to change track

    // Attach an event handler for when something changes on the system
    resultSet.ContentsChanged += ResultSet_ContentsChanged;

    await resultSet.GetFilesAsync();
}
var rtb = new RenderTargetBitmap();
        await rtb.RenderAsync(ImageHolder); // Render control to RenderTargetBitmap

        // Get pixels from RTB
        IBuffer pixelBuffer = await rtb.GetPixelsAsync();
        byte[] pixels = pixelBuffer.ToArray();

        // Support custom DPI
        DisplayInformation displayInformation = DisplayInformation.GetForCurrentView();
        StorageFile file = await KnownFolders.PicturesLibrary.CreateFileAsync("snapshot" + DateTime.Now.ToString("MM-dd-yyyy ss.fff") + ".jpg", CreationCollisionOption.GenerateUniqueName);
        using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
        {
            BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
            encoder.SetPixelData(BitmapPixelFormat.Bgra8, // RGB with alpha
                                 BitmapAlphaMode.Premultiplied,
                                 (uint)rtb.PixelWidth,
                                 (uint)rtb.PixelHeight,
                                 displayInformation.RawDpiX,
                                 displayInformation.RawDpiY,
                                 pixels);
            await encoder.FlushAsync();
        }
        await resultSet.GetFilesAsync();