Image downloaded with HttpClient is corrupt - c#

I am trying to save an image from the web to local storage to be manipulated later, but it appears to be corrupt and attempting to open it with an external application fails. Opening the image in the webbrowser works completely normally. Thanks for any help.
var client = new HttpClient();
var clientResponse = await client.GetByteArrayAsync(imageUri);
var temp = ApplicationData.Current.TemporaryFolder;
StorageFile file;
if ((await temp.GetFilesAsync()).Any(f => f.Name == "temp_image.png")) {
file = await temp.GetFileAsync("tempcolorizer.png");
} else {
file = await temp.CreateFileAsync("temp_image.png");
}
using (var fs = await file.OpenReadAsync())
using (var writer = new DataWriter(fs)) {
writer.WriteBytes(clientResponse);
}

You have to call StoreAsync:
using (var fs = await file.OpenReadAsync())
using (var writer = new DataWriter(fs)) {
writer.WriteBytes(clientResponse);
await writer.StoreAsync();
}

Related

Save recorded sound to project file in UWP

I recorded sound with the device's microphone but I don't know how to save it. Is it with the help of MediaCapture element, and if yes, then how to do it?
Here is a basic idea how to convert to mp3 and save in a file with Datawriter.
I wrote this code on the fly so its not tested.
MediaEncodingProfile _Profile = Windows.Media.MediaProperties.MediaEncodingProfile.CreateMp3(AudioEncodingQuality.High);
MediaTranscoder _Transcoder = new Windows.Media.Transcoding.MediaTranscoder();
CancellationTokenSource _cts = new CancellationTokenSource();
private void ConvertSteamToMp3()
{
IRandomAccessStream audio = buffer.CloneStream(); //your recoreded InMemoryRandomAccessStream
var folder = KnownFolders.MusicLibrary.CreateFolderAsync("MyCapturedAudio", CreationCollisionOption.OpenIfExists);
outputFile = await folder.CreateFileAsync("record.mp3", CreationCollisionOption.GenerateUniqueName);
using (IRandomAccessStream fileStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
{
var preparedTranscodeResult = await _Transcoder.PrepareStreamTranscodeAsync(audio, fileStream, _Profile);
if (preparedTranscodeResult.CanTranscode)
{
var progress = new Progress<double>(TranscodeProgress);
await preparedTranscodeResult.TranscodeAsync().AsTask(_cts.Token, progress);
}
using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
{
using (DataWriter dataWriter = new DataWriter(outputStream))
{
//TODO: Replace "Bytes" with the type you want to write.
dataWriter.WriteBytes(bytes);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
await outputStream.FlushAsync();
}
}
}
Or just save the stream in a file
public async SaveToFile()
{
IRandomAccessStream audio = buffer.CloneStream(); //your recoreded InMemoryRandomAccessStream
var folder = KnownFolders.MusicLibrary.CreateFolderAsync("MyCapturedAudio", CreationCollisionOption.OpenIfExists);
outputFile = await folder.CreateFileAsync("record.mp3", CreationCollisionOption.GenerateUniqueName);
using (IRandomAccessStream fileStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
{
await RandomAccessStream.CopyAndCloseAsync(audio.GetInputStreamAt(0), fileStream.GetOutputStreamAt(0));
await audio.FlushAsync();
audio.Dispose();
}
});
}

How do I write a binary file in a Windows Store App?

I'm trying to implement a StreamSocket communication and the server is now sending me a ".zip" file in byte[] chuncks. It looks like my byte[] in memory is fine (amount of bytes are the same as original .zip file in the server) but when I save those bytes in a file the unzip program says it's 'corrupted'.
I've tried several options but none of them worked for me:
1
var file = await StorageFile.CreateFileAsync();
using(var stream = await file.OpenStreamForWriteAsync())
{
stream.Write(myBytes, ...);
}
2
var file = await StorageFile.CreateFileAsync();
await FileIO.WriteBytesAsync(file, myBytes);
3
var file = await StorageFile.CreateFileAsync();
using (var fileStream = await file.OpenStreamForWriteAsync())
{
var sessionData = new MemoryStream(myBytes);
sessionData.Seek(0, SeekOrigin.Begin);
await sessionData.CopyToAsync(fileStream);
}
4
var file = await StorageFile.CreateFileAsync();
using (var writer = new BinaryWriter(await file.OpenStreamForWriteAsync())
{
writer.WriteBytes(myBytes);
}
If anyone has some new ideas please share.
Regards.

How to download and store an image using Windows.Web.Http?

How do I download and store a jpeg image from the internet in a Windows Store App with Windows.Web.Http?
The problem that I am facing is that I don't know what Get…Async and Write…Async method I must use for an image? It is very different with files, than with strings.
Only Windows.Web.Http!
No third-party solutions!
If you suggest something else, please use the comment section, not the answer. Thank you!
…
using Windows.Storage;
using Windows.Web.Http;
Uri uri = new Uri("http://image.tmdb.org/t/p/w300/" + posterPath);
HttpClient httpClient = new HttpClient();
// I guess I need to use one of the Get...Async methods?
var image = await httpClient.Get…Async(uri);
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFolder cachedPostersFolder = await localFolder.CreateFolderAsync("cached posters", CreationCollisionOption.OpenIfExists);
StorageFile posterFile = await cachedPostersFolder.CreateFileAsync(posterPath, CreationCollisionOption.ReplaceExisting);
// I guess I need to use one of the Write...Async methods?
await FileIO.Write…Async(posterFile, image);
You can get a buffer using the GetBufferAsync method and then call the FileIO.WriteBufferAsync to write the buffer to a file:
Uri uri = new Uri("http://i.stack.imgur.com/ZfLdV.png?s=128&g=1");
string fileName = "daniel2.png";
StorageFile destinationFile = await KnownFolders.PicturesLibrary.CreateFileAsync(
fileName, CreationCollisionOption.GenerateUniqueName);
HttpClient client = new HttpClient();
var buffer = await client.GetBufferAsync(uri);
await Windows.Storage.FileIO.WriteBufferAsync(destinationFile, buffer);
image1.Source = new BitmapImage(new Uri("http://www.image.com/image.jpg", UriKind.RelativeOrAbsolute));
using (var mediaLibrary = new MediaLibrary())
{
using (var stream = new MemoryStream())
{
var fileName = string.Format("Gs{0}.jpg", Guid.NewGuid());
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
var picture = mediaLibrary.SavePicture(fileName, stream);
if (picture.Name.Contains(fileName)) return true;
}
}
This is a similar answer to John's, however in WP8.1 you can't use GetBufferAsync. Instead you can use GetStreamAsync in the way that I have:
Uri uri = new Uri(UriString);
string fileName = p4.IconLocation;
HttpClient client = new HttpClient();
var streamImage = await client.GetStreamAsync(uri);
await SaveToLocalFolderAsync(streamImage, fileName);
using the function:
public async Task SaveToLocalFolderAsync(Stream file, string fileName)
{
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile storageFile = await localFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream outputStream = await storageFile.OpenStreamForWriteAsync())
{
await file.CopyToAsync(outputStream);
}
}

Save .mp4 to Windows Phone video library

I was wondering how I can download an MP4 video file from a URI and save it to the media library on Windows Phone 8.1.
It would be great if it worked in a Universal App - but it doesn't have to.
I found this code to save an image to the camera roll - do I go the same way about this with an *.mp4 to save it to the video library? And can I just hand off a download stream (not sure if that makes sense) to that function?
StorageFolder testFolder = await StorageFolder.GetFolderFromPathAsync(#"C:\test");
StorageFile sourceFile = await testFolder.GetFileAsync("TestImage.jpg");
StorageFile destinationFile = await KnownFolders.CameraRoll.CreateFileAsync("MyTestImage.jpg");
using (var sourceStream = await sourceFile.OpenReadAsync())
{
using (var sourceInputStream = sourceStream.GetInputStreamAt(0))
{
using (var destinationStream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite))
{
using (var destinationOutputStream = destinationStream.GetOutputStreamAt(0))
{
await RandomAccessStream.CopyAndCloseAsync(sourceInputStream, destinationStream);
}
}
}
}
So I finally figured it out, this is what my code looks like:
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var file = await response.Content.ReadAsByteArrayAsync();
StorageFile destinationFile
= await KnownFolders.SavedPictures.CreateFileAsync("file.mp4",
CreationCollisionOption.ReplaceExisting);
Windows.Storage.Streams.IRandomAccessStream stream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite);
IOutputStream output = stream.GetOutputStreamAt(0);
DataWriter writer = new DataWriter(output);
writer.WriteBytes(file);
await writer.StoreAsync();
await output.FlushAsync();
}

decompress a ZIP file on windows 8 C#

I am building a metro style app for windows 8 and I have a zip file that I am downloading from a web service, and I want to extract it.
I have seen the sample for compression and decompression, but that takes a single file an compresses/decompresses it. I have a whole directory structure that I need to extract.
Here is what I have so far:
var appData = ApplicationData.Current;
var file = await appData.LocalFolder.GetItemAsync("thezip.zip") as StorageFile;
var decompressedFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("tempFileName", CreationCollisionOption.GenerateUniqueName);
using (var decompressor = new Decompressor(await file.OpenSequentialReadAsync()))
using (var decompressedOutput = await decompressedFile.OpenAsync(FileAccessMode.ReadWrite))
{
var bytesDecompressed = await RandomAccessStream.CopyAsync(decompressor, decompressedOutput);
}
But this is no good, the bytesDecompressed variable is always zero size, but the zip File is 1.2MB
Any help here would be greatly appreciated.
EDIT: Answer, thanks to Mahantesh
Here is the code for unzipping a file:
private async void UnZipFile()
{
var folder = ApplicationData.Current.LocalFolder;
using (var zipStream = await folder.OpenStreamForReadAsync("thezip.zip"))
{
using (MemoryStream zipMemoryStream = new MemoryStream((int)zipStream.Length))
{
await zipStream.CopyToAsync(zipMemoryStream);
using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.Name != "")
{
using (Stream fileData = entry.Open())
{
StorageFile outputFile = await folder.CreateFileAsync(entry.Name, CreationCollisionOption.ReplaceExisting);
using (Stream outputFileStream = await outputFile.OpenStreamForWriteAsync())
{
await fileData.CopyToAsync(outputFileStream);
await outputFileStream.FlushAsync();
}
}
}
}
}
}
}
}
In Metro style apps, you work with compressed files by using the methods in the ZipArchive, ZipArchiveEntry, DeflateStream, and GZipStream classes.
Refer : UnZip File in Metro
Refer : Folder zip/unzip in metro c#
Based on your code and suggestions, I came up with one which supports folders extraction, which was one of my needs:
private async void UnZipFile(string file)
{
var folder = ApplicationData.Current.LocalFolder;
using (var zipStream = await folder.OpenStreamForReadAsync(file))
{
using (MemoryStream zipMemoryStream = new MemoryStream((int)zipStream.Length))
{
await zipStream.CopyToAsync(zipMemoryStream);
using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.Name == "")
{
// Folder
await CreateRecursiveFolder(folder, entry);
}
else
{
// File
await ExtractFile(folder, entry);
}
}
}
}
}
}
private async Task CreateRecursiveFolder(StorageFolder folder, ZipArchiveEntry entry)
{
var steps = entry.FullName.Split('/').ToList();
steps.RemoveAt(steps.Count() - 1);
foreach (var i in steps)
{
await folder.CreateFolderAsync(i, CreationCollisionOption.OpenIfExists);
folder = await folder.GetFolderAsync(i);
}
}
private async Task ExtractFile(StorageFolder folder, ZipArchiveEntry entry)
{
var steps = entry.FullName.Split('/').ToList();
steps.RemoveAt(steps.Count() - 1);
foreach (var i in steps)
{
folder = await folder.GetFolderAsync(i);
}
using (Stream fileData = entry.Open())
{
StorageFile outputFile = await folder.CreateFileAsync(entry.Name, CreationCollisionOption.ReplaceExisting);
using (Stream outputFileStream = await outputFile.OpenStreamForWriteAsync())
{
await fileData.CopyToAsync(outputFileStream);
await outputFileStream.FlushAsync();
}
}
}

Categories

Resources