Encrypt & Decrypt Local Images in Windows Store App - c#

I'm building a Windows Store App including a local folder of Images.
I want to protect all the Images so they can't be accessed from:
C:\Users[username]\AppData\Local\Packages\LocalState\Settings\settings.dat
I know I should encrypt and decrypt the Images using the DataProtectionProvider class, but the documentation only shows how to encrypt/decrypt strings...
How should I convert a Bitmap image into a byte array? or should I encode it with Base64? Is there any tutorial or sample using this process?

It's easiest if the images you want to encrypt are loaded from files and written back out to files. Then you can do:
async void EncryptFile(IStorageFile fileToEncrypt, IStorageFile encryptedFile)
{
IBuffer buffer = await FileIO.ReadBufferAsync(fileToEncrypt);
DataProtectionProvider dataProtectionProvider =
new DataProtectionProvider(ENCRYPTION_DESCRIPTOR);
IBuffer encryptedBuffer =
await dataProtectionProvider.ProtectAsync(buffer);
await FileIO.WriteBufferAsync(encryptedFile, encryptedBuffer);
}
DataProtectionProvider.ProtectStreamAsync is another alternative if you can get stream instances from your inputs and outputs. For example, if you have a byte[] containing your image data then you can create an in-memory input stream from it:
byte[] imageData = ...
using (var inputMemoryStream = new MemoryStream(imageData).AsInputStream())
{
...
}
Edit: Then for example to decrypt the file and display it in an Image control you could do:
var encryptedBuffer = await FileIO.ReadBufferAsync(encryptedFile);
var dataProtectionProvider = new DataProtectionProvider();
var buffer = await dataProtectionProvider.UnprotectAsync(encryptedBuffer);
var bmp = new BitmapImage();
await bmp.SetSourceAsync(buffer.AsStream().AsRandomAccessStream());
imageControl.Source = bmp;

public async void Protect()
{
for (int i = 1; i < 24; i++)
{
string imageFile = ImagePages[i];
var fileToEncrypt = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(imageFile);
var encryptedFile1 = await ApplicationData.Current.LocalFolder.CreateFileAsync("encryptedPage" + i);
var encryptedFile2 = await EncryptFile(fileToEncrypt, encryptedFile1);
IBuffer buffer = await DecryptFile(encryptedFile2);
//(2.) It goes here and throw the 'System.ArgumentException' having the encryptedFile's ContentType=""
var bmp = new BitmapImage();
await bmp.SetSourceAsync(buffer.AsStream().AsRandomAccessStream());
//Fill the List responsible for the Portrait View
MyPortrait mp = new MyPortrait();
mp.onlyImage = bmp;
PImageList.Add(mp);
}
}
public async Task<IStorageFile> EncryptFile(IStorageFile fileToEncrypt, IStorageFile encryptedFile)
{
IBuffer buffer = await FileIO.ReadBufferAsync(fileToEncrypt);
//I have no more exceptions here
DataProtectionProvider dataProtectionProvider = new DataProtectionProvider("LOCAL=user");
IBuffer encryptedBuffer = await dataProtectionProvider.ProtectAsync(buffer);
//(1.) After arriving here when deploying it goes to (2.)
await FileIO.WriteBufferAsync(encryptedFile, encryptedBuffer);
return encryptedFile;
}
public async Task<IBuffer> DecryptFile(IStorageFile encryptedFile)
{
var protectedBuffer = await FileIO.ReadBufferAsync(encryptedFile);
var dataProtectionProvider = new DataProtectionProvider();
var buffer = await dataProtectionProvider.UnprotectAsync(protectedBuffer);
return buffer;
}

Related

YoutubeExplode with Azure Speech to Text

I have to create a translated audio version for a YouTube video so I'm using YoutubeExplode to download the audio file:
var youtubeClient = new YoutubeClient();
var video = await youtubeClient.Videos.GetAsync(videoUrl);
var streamManifest = await youtubeClient.Videos.Streams.GetManifestAsync(video.Id);
var audioStreamInfo = streamManifest.GetAudioOnlyStreams().GetWithHighestBitrate();
var stream = await youtubeClient.Videos.Streams.GetAsync(audioStreamInfo);
Then I've created a Speech Azure Cognitive Service to generate the translated audio file and here is my code:
var speechTranslateConfig = SpeechTranslationConfig.FromSubscription("key", "region");
var text = await SpeechToText(speechTranslateConfig, stream);
async Task<string> SpeechToText(SpeechTranslationConfig config, Stream stream)
{
config.SpeechRecognitionLanguage = "en-US";
config.AddTargetLanguage("ro");
using var audioInputStream = AudioInputStream.CreatePushStream();
using var audioConfig = AudioConfig.FromStreamInput(audioInputStream);
using var recognizer = new TranslationRecognizer(config, audioConfig);
var bytes = streamToByteArray(stream);
audioInputStream.Write(bytes);
var result = await recognizer.RecognizeOnceAsync();
return result.Text;
}
private static byte[] streamToByteArray(Stream input)
{
MemoryStream ms = new MemoryStream();
input.CopyTo(ms);
return ms.ToArray();
}
I'm trying to use Stream because I don't want to save the original audio file, but the impediment I'm facing is that the translation result is always an empty string.
I also tried to save the original file and translate it (instead of converting the stream to a byte array) and like this, all works fine.
I can't understand what I'm missing, because I followed the documentation.

Uwp Display Image From Table SQL

I have a function On my wcf service it returns Image as Bytes
I didnt Find any idea on how to display it in my Image Control
How can i Convert Those Bytes to an Image And thanks !
Here is my WCF Function:
public List<Data.Product> Show_P()
{
DataTable Table = new DataTable();
List<Data.Product> MyProductsLIST = new List<Data.Product>();
Table = Sp.SelectData("Show_Products", null);
if (Table.Rows.Count > 0)
for (int i = 0; i < Table.Rows.Count; i++)
{
Data.Product Log = new Data.Product();
Log._ID = Convert.ToInt32(Table.Rows[i]["ID"]);
Log._Name = Table.Rows[i]["Name"].ToString();
Log._Price = Table.Rows[i]["Price"].ToString();
Log._Qte = Table.Rows[i]["Qte"].ToString();
Log._CAT = Convert.ToInt32(Table.Rows[i]["Cat"]);
Log._Vote = Convert.ToInt32(Table.Rows[i]["Vote"]);
Log._Image = (byte[])Table.Rows[i]["Image"];
MyProductsLIST.Add(Log);
}
return MyProductsLIST;
}
And in my uwp :
public static List<Products> Get_Products()
{
MspService.Service1Client Serv = new MspService.Service1Client();
MspService.Product[] Product = Serv.Show_PAsync().Result.Show_PResult;
List<Products> Produc = new List<Design_TesTiNg.MenuBox.Products>();
for (int i = 0; i < Product.Length; i++)
{
Products Prod = new Products();
Prod._ID = Product[i]._ID;
Prod._Name = Product[i]._Name;
Prod._Price = Product[i]._Price;
Prod._Qte = Product[i]._Qte;
Prod._CAT = Product[i]._CAT;
Prod._Vote = Product[i]._Vote;
Prod._Image = Product[i]._Image;
Prod.ms = new MemoryStream(Prod._Image);
Convert(Prod.ms,Prod._Img);
Produc.Add(Prod);
}
return Produc;
}
So I tried to convert it that way :
public static async void Convert(MemoryStream mem, BitmapImage Img)
{
IRandomAccessStream a1 = await ConvertToRandomAccessStream(mem);
Img = new BitmapImage();
await Img.SetSourceAsync(a1);
}
public static async Task<IRandomAccessStream> ConvertToRandomAccessStream(MemoryStream memoryStream)
{
var randomAccessStream = new InMemoryRandomAccessStream();
var outputStream = randomAccessStream.GetOutputStreamAt(0);
var dw = new DataWriter(outputStream);
var task = Task.Factory.StartNew(() => dw.WriteBytes(memoryStream.ToArray()));
await task;
await dw.StoreAsync();
await outputStream.FlushAsync();
return randomAccessStream;
}
it returns Image as Bytes I didnt Find any idea on how to display it in my Image Control
From your code Log._Image = (byte[])Table.Rows[i]["Image"];, I think your Bytes means byte array here. I think problem is you need to know how your images are converted from image to byte arrays. I assumed that your wcf is for saving data (include byte arrays of images) to table and retrieve them, your converting images to byte arrays work is still done in the UWP app, then I've tested your code, if I convert image to byte array in UWP app in this way:
var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/1.jpeg"));
var b64 = await ConvertStorageFileToBase64String(file);
private async Task<byte[]> ConvertStorageFileToBase64String(StorageFile File)
{
var stream = await File.OpenReadAsync();
using (var dataReader = new DataReader(stream))
{
var bytes = new byte[stream.Size];
await dataReader.LoadAsync((uint)stream.Size);
dataReader.ReadBytes(bytes);
return bytes;
}
}
And convert back using your method like this:
MemoryStream mem = new MemoryStream(b64);
IRandomAccessStream a1 = await ConvertToRandomAccessStream(mem);
var Img = new BitmapImage();
await Img.SetSourceAsync(a1);
myimg.Source = Img; //myimg is the name of the image control.
The image can be correctly showed in image control. So if your code can't work by your side, please update your code for converting image to byte array, or maybe you can upload your sample so can we have a test.

WriteableBitmap to Base64 c#

First of all,I'm sorry for my poor English.
I work on this project for few days without any solution for my problem. I try to send a picture from my UWP application to a Webservice in c#. I did this thing in a android app without any problem.
I should encode a image into a base64 string that the webservice can decode it.
I have two issues , the first is that if I try ( with a online decoder) to decode my base64 string, this gave me something like this with this code.
In the image, we can see the it have not show the whole picture.:
I write it with this code to base64:
private async void ToBase64(WriteableBitmap img)
{
var encoded = new InMemoryRandomAccessStream();
// Copy buffer to pixels
byte[] pixels;
using (var stream = img.PixelBuffer.AsStream())
{
pixels = new byte[(uint)stream.Length];
await stream.ReadAsync(pixels, 0, pixels.Length);
}
var encoder = await BitmapEncoder
.CreateAsync(BitmapEncoder.PngEncoderId, encoded);
encoder.SetPixelData(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied, (uint)img.PixelWidth, (uint)img.PixelHeight
, 96, 96, pixels);
await encoder.FlushAsync();
encoded.Seek(0);
var array = new byte[encoded.Size];
await encoded.AsStream().ReadAsync(array, 0, array.Length);
Base64String = Convert.ToBase64String(array);
}
My second issue is that if I try to send this Base64 to my webservices and decode it with FromBase64String, the webservice return an error "The base64 string format is not correct". I don't understand it because as we can see, online decoder can decode it and i don't have this issue with android app.
If you have any ideas about this issues.
I tried multiple things that i saw on internet
Thank you per advance.
EDIT 1
This is my decode method. This method work with Bitmap base64 send with android app.
[WebMethod]
public string uploadPhoto(string image)
{
byte[] bytes = Convert.FromBase64String(image);
using (var imageFile = new FileStream("directory+filename", FileMode.Create))
{
imageFile.Write(bytes, 0, bytes.Length);
imageFile.Flush();
}
return number;
}
EDIT 2
It works with this code :
public async Task<String> SaveToBytesAsync(ImageSource imageSource)
{
byte[] imageBuffer;
var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
var file = await localFolder.CreateFileAsync("temp.jpg", CreationCollisionOption.ReplaceExisting);
using (var ras = await file.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.None))
{
WriteableBitmap bitmap = imageSource as WriteableBitmap;
var stream = bitmap.PixelBuffer.AsStream();
byte[] buffer = new byte[stream.Length];
await stream.ReadAsync(buffer, 0, buffer.Length);
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, ras);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96.0, 96.0, buffer);
await encoder.FlushAsync();
var imageStream = ras.AsStream();
imageStream.Seek(0, SeekOrigin.Begin);
imageBuffer = new byte[imageStream.Length];
var re = await imageStream.ReadAsync(imageBuffer, 0, imageBuffer.Length);
}
await file.DeleteAsync(StorageDeleteOption.Default);
return Convert.ToBase64String(imageBuffer);
}
the decoding on the server give a full image.
Thanks.
is there a reason to encode the image?, try this.
string base64String = await ToBase64Async(bitmap);
public async Task<string> ToBase64Async(WriteableBitmap bitmap)
{
using (Stream stream = bitmap.PixelBuffer.AsStream())
{
stream.Position = 0;
var reader = new DataReader(stream.AsInputStream());
var bytes = new byte[stream.Length];
await reader.LoadAsync((uint)stream.Length);
reader.ReadBytes(bytes);
return Convert.ToBase64String(bytes);
}
}
Try use the code to base64
private async Task<string> ToBase64(Image control)
{
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(control);
return await ToBase64(bitmap);
}
And if you have a WriteableBitmap ,try use the code:
private async Task<string> ToBase64(WriteableBitmap bitmap)
{
var bytes = bitmap.PixelBuffer.ToArray();
return await ToBase64(bytes, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight);
}
If your image is a SotrageFile,you can use
private async Task<string> ToBase64(StorageFile bitmap)
{
var stream = await bitmap.OpenAsync(Windows.Storage.FileAccessMode.Read);
var decoder = await BitmapDecoder.CreateAsync(stream);
var pixels = await decoder.GetPixelDataAsync();
var bytes = pixels.DetachPixelData();
return await ToBase64(bytes, (uint)decoder.PixelWidth, (uint)decoder.PixelHeight, decoder.DpiX, decoder.DpiY);
}
If your picture is RenderTargetBitmap
private async Task<string> ToBase64(RenderTargetBitmap bitmap)
{
var bytes = (await bitmap.GetPixelsAsync()).ToArray();
return await ToBase64(bytes, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight);
}
See https://codepaste.net/ijx28i
http://lindexi.oschina.io/lindexi/post/win10-uwp-%E8%AF%BB%E5%8F%96%E4%BF%9D%E5%AD%98WriteableBitmap-BitmapImage/

Windows 8 How to open a BitmapImage as a stream?

In a Windows 8 app, how do I convert a BitmapImage to a Stream? I have a List of BitmapImages and I'm going to use that List to upload each image to a server and I need to use a Stream to do that. So is there a way to convert each individual BitmapImage into a Stream?
No, there isn't. You need to track the original sources or use a WriteableBitmap instead.
Retrieve the bitmap image:
public async void ContinueFileOpenPicker(FileOpenPickerContinuationEventArgs args)
{
if (args.Files.Count > 0)
{
var imageFile = args.Files[0] as StorageFile;
// Ensure the stream is disposed once the image is loaded
using (IRandomAccessStream fileStream = await imageFile.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
// Set the image source to the selected bitmap
BitmapImage bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(fileStream);
ImageControl.Source = bitmapImage;
await _viewModel.Upload(imageFile);
}
}
}
Create the file stream:
internal async Task Upload(Windows.Storage.StorageFile file)
{
var fileStream = await file.OpenAsync(FileAccessMode.Read);
fileStream.Seek(0);
var reader = new Windows.Storage.Streams.DataReader(fileStream.GetInputStreamAt(0));
await reader.LoadAsync((uint)fileStream.Size);
Globals.MemberId = ApplicationData.Current.LocalSettings.Values[Globals.PROFILE_KEY];
var userName = "Rico";
var sex = 1;
var url = string.Format("{0}{1}?memberid={2}&name={3}&sex={4}", Globals.URL_PREFIX, "api/Images", Globals.MemberId, userName,sex);
byte[] image = new byte[fileStream.Size];
await UploadImage(image, url);
}
Create a memory stream from the image:
public async Task UploadImage(byte[] image, string url)
{
Stream stream = new System.IO.MemoryStream(image);
HttpStreamContent streamContent = new HttpStreamContent(stream.AsInputStream());
Uri resourceAddress = null;
Uri.TryCreate(url.Trim(), UriKind.Absolute, out resourceAddress);
Windows.Web.Http.HttpRequestMessage request = new Windows.Web.Http.HttpRequestMessage(Windows.Web.Http.HttpMethod.Post, resourceAddress);
request.Content = streamContent;
var httpClient = new Windows.Web.Http.HttpClient();
var cts = new CancellationTokenSource();
Windows.Web.Http.HttpResponseMessage response = await httpClient.SendRequestAsync(request).AsTask(cts.Token);
}

Converting an Image to Byte Array in Windows Store App

In WindowsStoreApps i want to convert an Local Image from solution explorer to byte array and then to base64 string.please guide me.The code I have tried so far is as below.
public async Task<string> ToBase64()
{
Byte[] ByteResult = null;
string bs64 = null;
if (url != null)
{
HttpClient client = new HttpClient();
ByteResult = await client.GetByteArrayAsync(url);
}
bs64 = Convert.ToBase64String(ByteResult);
return bs64;
}
Suppose you want to convert an image named MyImage.png from Assets folder then below code will return the base64 string of that image.
private async Task DoWork()
{
var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/MyImage.png"));
var b64 = await ConvertStorageFileToBase64String(file);
}
private async Task<string> ConvertStorageFileToBase64String(StorageFile File)
{
var stream = await File.OpenReadAsync();
using (var dataReader = new DataReader(stream))
{
var bytes = new byte[stream.Size];
await dataReader.LoadAsync((uint)stream.Size);
dataReader.ReadBytes(bytes);
return Convert.ToBase64String(bytes);
}
}
Try this piece of code
StorageFile file = <Your File>;
var bytes = new Byte[0];
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read))
{
var reader = new DataReader(fileStream.GetInputStreamAt(0));
bytes = new Byte[fileStream.Size];
await reader.LoadAsync((uint)fileStream.Size);
reader.ReadBytes(bytes);
}
string imageInStringFormat = Convert.ToBase64String(bytes);

Categories