How to get isolated storage image as stream? - c#-4.0

I have very uncommon problem. firstly let me tell you that i want to build a WP8 apps about images. I have some images stored in the project solution and using those for the apps and it is working fine.
i am using one
public Stream ImageStream
{
get
{
return this.imageStream;
}
set
{
this.imageStream = value;
}
}
Now for the project solution images this Image stream i am calling like this
StreamResourceInfo imageRes = Application.GetResourceStream(new Uri("WindowsPhone;component/Images/Image1.jpg", UriKind.Relative));
this.ImageStream = imageRes.Stream;
Now the problem begins if I try to use any image from media library. I can store the file into Isolated storage and from their I can access the file. What I am doing is
using (IsolatedStorageFile Iso = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var stream = new IsolatedStorageFileStream(strFileName, FileMode.Open, FileAccess.Read, Iso))
{
IsolatedStorageFileStream fileStream = Iso.OpenFile(strFileName, FileMode.Open, FileAccess.Read);
data = new byte[stream.Length];
// Read the entire file and then close it
stream.Read(data, 0, data.Length);
stream.Close();
}
}
MemoryStream ms = new MemoryStream(data);
BitmapImage bi = new BitmapImage();
// Set bitmap source to memory stream
bi.SetSource(ms);
However i can use the image file and can show but you can see it is a bit map image, and as it is in isolated storage I can not use
StreamResourceInfo imageRes ...
this.ImageStream = ...
Any help how can I use this.ImageSteam Properties? any other ideas will be welcome. I am actually beginner in WP8 programming
Or Let me ask you a simple Question how can I read a image which is in isolatedstorage to StreamResourceInfo ?
If I can do that my problem is solved. please help me.

*Save Image to Isolated Storage: *
String tempJPEG = "logo.jpg";
// Create virtual store and file stream. Check for duplicate tempJPEG files.
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists(tempJPEG))
{
myIsolatedStorage.DeleteFile(tempJPEG);
}
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(tempJPEG);
StreamResourceInfo sri = null;
Uri uri = new Uri(tempJPEG, UriKind.Relative);
sri = Application.GetResourceStream(uri);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(sri.Stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
// Encode WriteableBitmap object to a JPEG stream.
Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
//wb.SaveJpeg(fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
fileStream.Close();
}
Happy Coding...

why execute a stream copy ?
http://www.windowsphonegeek.com/tips/All-about-WP7-Isolated-Storage---Read-and-Save-Images
try something like
BitmapImage bi = new BitmapImage();
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile("logo.jpg", FileMode.Open, FileAccess.Read))
{
bi.SetSource(fileStream);
this.img.Height = bi.PixelHeight;
this.img.Width = bi.PixelWidth;
}
}
this.img.Source = bi;

Related

BlockBlobClient.UploadAsync fails when trying to modify the incoming WatchableReadStream object

I hope you're having some advice because I'm pretty much out of options. What I'm trying to do:
upload an image to a blobcontainer via the azure portal
when doing that, the blobtrigger below fires.
I want to resize the incoming image which is a Microsoft.Azure.WebJobs.Host.Blobs.WatchableReadStream object.
I want to upload the result to a new blob container.
The issue is, when I am passing any other Stream, e.g. a MemoryStream than the unmodified myBlob object the UploadAsync method seems to silently fail and the BlobTrigger fires again, starting an endless loop. Writing to the current myBlob object also silently fails. Only thing which works is passing the myBlob object in BlockBlobClient.UploadAsync without ANY modification whatsoever, which is useless. I am doing a remote debugging session in Azure.
Also, when I try to feed a MemoryStream object to the UploadAsync method the same problem occurs. The method below is the blob trigger:
public async Task UploadImage([BlobTrigger("mediafullsizecontainer/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob, string name, ILogger log)
{
BlockBlobClient fullsizeBlobClient = _mediaFullsizeContainerClient.GetBlockBlobClient(name);
Response<BlobProperties> blobPropertiesResponse = await fullsizeBlobClient.GetPropertiesAsync(null, default);
BlobProperties blobProperties = blobPropertiesResponse.Value;
//Only process blobs when the correct metadata properties are set
if (blobProperties.Metadata.Any(property => property.Key == "category" & property.Value != String.Empty))
{
string category = blobProperties.Metadata["category"];
Stream s = await ResizeImage(myBlob);
BlockBlobClient thumbnailBlobclient = _mediaThumbnailContainerClient.GetBlockBlobClient(name);
Response<BlobContentInfo> uploadResponse = await thumbnailBlobclient.UploadAsync(s, new BlobUploadOptions(), default);
BlobContentInfo blobContentInfo = uploadResponse.Value;
}
}
The ResizeImage method uses the SixLabors.ImageSharp image processing library.
public async Task<Stream> ResizeImage(Stream inputStream)
{
(Image image, IImageFormat imageFormat) imageWithFormat = await Image.LoadWithFormatAsync(inputStream);
int height = imageWithFormat.image.Height;
int width = imageWithFormat.image.Width;
imageWithFormat.image.Mutate(operation => {
operation.Resize(width / 4, height / 4);
});
MemoryStream outputStream = new MemoryStream();
imageWithFormat.image.Save(outputStream, imageWithFormat.imageFormat);
return outputStream;
}
So when I do a mock change on the myBlob object like this, myBlob.Write(buffer) fails:
byte[] buffer = new byte[myBlob.Length];
myBlob.Read(buffer, 0, (int)myBlob.Length);
myBlob.Position = 0;
myBlob.Write(buffer);
When I copy the myBlob contents to a MemoryStream and pass the memoryStream to UploadAsync, UploadAsync fails:
MemoryStream ms = new MemoryStream();
myBlob.CopyTo(ms);
BlockBlobClient thumbnailBlobclient = _mediaThumbnailContainerClient.GetBlockBlobClient(name);
Response<BlobContentInfo> uploadResponse = await thumbnailBlobclient.UploadAsync(ms, new BlobUploadOptions(), default);
Only thing which works is passing the myBlob object without any modification to UploadAsync which is useless since I need to modify the incoming stream:
public async Task UploadImage([BlobTrigger("mediafullsizecontainer/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob, string name, ILogger log)
{
BlockBlobClient fullsizeBlobClient = _mediaFullsizeContainerClient.GetBlockBlobClient(name);
Response<BlobProperties> blobPropertiesResponse = await fullsizeBlobClient.GetPropertiesAsync(null, default);
BlobProperties blobProperties = blobPropertiesResponse.Value;
//Only process blobs when the correct metadata properties are set
if (blobProperties.Metadata.Any(property => property.Key == "category" & property.Value != String.Empty))
{
string category = blobProperties.Metadata["category"];
BlockBlobClient thumbnailBlobclient = _mediaThumbnailContainerClient.GetBlockBlobClient(name);
Response<BlobContentInfo> uploadResponse = await thumbnailBlobclient.UploadAsync(myBlob, new BlobUploadOptions(), default);
BlobContentInfo blobContentInfo = uploadResponse.Value;
}
}
How can I pass a custom stream to the UploadAsync method? The documentation on https://learn.microsoft.com/en-us/dotnet/api/azure.storage.blobs.specialized.blockblobclient.uploadasync?view=azure-dotnet says you just need a stream object - but this does not work. Thanks in advance.
Ok looks like I found the answer myself, I got rid of the dreaded UploadAsync method and did it like this by reading the outputStream of the resized image into a buffer then opening a Stream for writing to the thumbnailBlobclient object and passing the buffer to the stream object. It makes sense that trying to modify the incoming myBlob object which came with the trigger, fires the trigger again and creating a loop.
Stream outputStream = await ResizeAndCropImage(myBlob);
byte[] buffer = new byte[outputStream.Length];
outputStream.Read(buffer);
BlockBlobClient thumbnailBlobclient = _mediaThumbnailContainerClient.GetBlockBlobClient(name);
Stream s = thumbnailBlobclient.OpenWrite(true, new BlockBlobOpenWriteOptions { HttpHeaders = new BlobHttpHeaders { ContentType = "image/jpg" } }, default); //set http headers here as well?
await s.WriteAsync(buffer);
s.Close();
I will set the content type in a more generic way but this concept is working.

Image downloaded from Azure Storage not being displayed

I'm new to Xamarin. I'm trying display a list of downloaded images. I am downloading images from an APP API on Azure, where I stored the file on Azure Storage.
My server code is the following:
public HttpResponseMessage Get(string PK, string RK)
{
//Creating CloudBlockBlolb...
byte[] bytes = new byte[blockBlob.Properties.Length]
for(int i = 0; i < blockBlob.Properties.Length; i++){
bytes[i] = 0x20;
}
blockBlob.DownloadToByteArray(bytes, 0);
HttpResponseMessage resp = new HttpResponseMessage(HttpStatusCode.OK);
resp.Content = new ByteArrayContent(bytes);
resp.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/jpg");
return resp;
}
My Xamarin code is the following:
public MainPage ()
{
//...
List<PicturePost> list = new List<PicturePost>{
new PicturePost("title", "subtitle", "link/api/Pictures?PK=xxx&RK=yyy")
};
InitializeComponent ();
listView.ItemTemplate = new DataTemplate (typeof(CustomImageCell));
listView.HasUnevenRows = true;
listView.ItemsSource = list;
//...
}
And here is the relevant code for CustomImageCell:
var image = new Image ();
image.SetBinding (Image.SourceProperty, "image");
//...
horizontalLayout.Children.Add (image);
I know that my API call works, because when I test it on the browser, it returns the image. I also know that if I use any random links such as http://www.natureasia.com/common/img/splash/thailand.jpg the image is downloaded and displayed properly. It is only when I use the API link that it doesn't seem to be working. Can someone tell me what I am doing wrong?
so in my public MainPage(), I added the following:
listView.BeginRefresh ();
listView.EndRefresh ();
I realized at some point that the images would take some time to download. I assume that when the listView was created, the images were not finished downloading, so I added the code above... Pretty sure this is not the best way to do this (probably an await would be better, but I don't know where).

ogg to mp3 using NAudio MFT

Here, I am having a problem while converting ogg file to mp3 format. Reading ogg file is done successfully but while encoding it is throwing exception like,"Exception from HRESULT: 0xC00D3E85". Presently I am working on windows server 2012(64 bit).
public byte[] DecodeOGG(byte[] data,string trgtfilename,int bitrate)
{
byte[] dt = null;
NVorbis.NAudioSupport.VorbisWaveReader vr = null;
using(MemoryStream ms = new MemoryStream(data))
{
ms.Position = 0;
vr = new NVorbis.NAudioSupport.VorbisWaveReader(ms);
}
var samp = new SampleChannel(vr);
var ws = new SampleToWaveProvider16(samp);
MediaFoundationEncoder.EncodeToMp3(ws, trgtfilename, bitrate);
}
You need to call MediaFoundationInterop.Startup() somewhere in your application. NAudio may be updated in the future to call this automatically.

Merge memorystreams to one iText document

I have four MemoryStreams of data that I want to merge and then open the pdfDocument, without creating a single file.
It's possible to write them down to files and then merge them but that would be bad practice and that can also cause a few issues so I want to avoid that.
However, I can not find a way to merge the MemoryStreams with iText5 for .NET.
Right now, this is how I do it with files:
private static void ConcatenateDocuments()
{
var stream = new MemoryStream();
var readerFrontPage = new PdfReader(Folder + FrontPageName);
var readerDocA = new PdfReader(Folder + docA);
var readerDocB = new PdfReader(Folder + DocB);
var readerAppendix = new PdfReader(Folder + Appendix);
var pdfCopyFields = new PdfCopyFields(stream);
pdfCopyFields.AddDocument(readerFrontPage);
pdfCopyFields.AddDocument(readerDocA );
pdfCopyFields.AddDocument(readerDocB);
pdfCopyFields.AddDocument(readerAppendix);
pdfCopyFields.Close();
SavePdf(stream, FilenameReport);
}
Since I need to remove the use of files, I keep the MemoryStream's as the different parts are built from different resources. So I have references to these memorystreams.
How can this be done?
The error PDF header signature not found can be fixed in this case by setting the stream's Position back to 0. Since you're not getting the error Cannot access a closed Stream I'm assuming that you are already correctly setting the PdfWriter's CloseStream to false.
Below is a full working C# 2010 WinForm app targeting iTextSharp 5.1.1.0 that creates three PDFs in MemoryStreams and combines them. Since I don't have a web server handy I'm writing them to disk.
using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//Create three MemoryStreams
MemoryStream[] streams = { CreateDoc("Page 1"), CreateDoc("Page 2"), CreateDoc("Page 3") };
//I don't have a web server handy so I'm going to write my final MemoryStream to a byte array and then to disk
byte[] bytes;
//Create our final combined MemoryStream
using (MemoryStream finalStream = new MemoryStream())
{
//Create our copy object
PdfCopyFields copy = new PdfCopyFields(finalStream);
//Loop through each MemoryStream
foreach (MemoryStream ms in streams)
{
//Reset the position back to zero
ms.Position = 0;
//Add it to the copy object
copy.AddDocument(new PdfReader(ms));
//Clean up
ms.Dispose();
}
//Close the copy object
copy.Close();
//Get the raw bytes to save to disk
bytes = finalStream.ToArray();
}
//Write out the file to the desktop
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Combined.pdf");
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
fs.Write(bytes, 0, bytes.Length);
}
this.Close();
}
/// <summary>
/// Helper method to create temporary documents
/// </summary>
private MemoryStream CreateDoc(string name)
{
MemoryStream ms = new MemoryStream();
using (Document doc = new Document(PageSize.LETTER))
{
using (PdfWriter writer = PdfWriter.GetInstance(doc, ms))
{
writer.CloseStream = false;
doc.Open();
doc.Add(new Paragraph(name));
doc.Close();
}
}
return ms;
}
}
}
While it seams the PdfReader can not take the stream, the array of the stream works.
var readerFrontPage = new PdfReader(streamFrontPage.ToArray());

GDI+ Generic Error

When my images are being loaded from my database on my web server, I see the following error:
A generic error occurred in GDI+. at
System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder,
EncoderParameters encoderParams) at
System.Drawing.Image.Save(Stream stream, ImageFormat format) at
MyWeb.Helpers.ImageHandler.ProcessRequest(HttpContext context)
All my code is attempting to do is load the image, can anybody take a look and let me know what I'm doing wrong?
Note - This works if I test it on my local machine, but not when I deploy it to my web server.
public void ProcessRequest(HttpContext context)
{
context.Response.Clear();
if (!String.IsNullOrEmpty(context.Request.QueryString["imageid"]))
{
int imageID = Convert.ToInt32(context.Request.QueryString["imageid"]);
int isThumbnail = Convert.ToInt32(context.Request.QueryString["thumbnail"]);
// Retrieve this image from the database
Image image = GetImage(imageID);
// Make it a thumbmail if requested
if (isThumbnail == 1)
{
Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);
image = image.GetThumbnailImage(200, 200, myCallback, IntPtr.Zero);
}
context.Response.ContentType = "image/png";
// Save the image to the OutputStream
image.Save(context.Response.OutputStream, ImageFormat.Png);
}
else
{
context.Response.ContentType = "text/html";
context.Response.Write("<p>Error: Image ID is not valid - image may have been deleted from the database.</p>");
}
}
The error occurs on the line:
image.Save(context.Response.OutputStream, ImageFormat.Png);
UPDATE
I've changed my code to this, bit the issue still happens:
var db = new MyWebEntities();
var screenshotData = (from screenshots in db.screenshots
where screenshots.id == imageID
select new ImageModel
{
ID = screenshots.id,
Language = screenshots.language,
ScreenshotByte = screenshots.screen_shot,
ProjectID = screenshots.projects_ID
});
foreach (ImageModel info in screenshotData)
{
using (MemoryStream ms = new MemoryStream(info.ScreenshotByte))
{
Image image = Image.FromStream(ms);
// Make it a thumbmail if requested
if (isThumbnail == 1)
{
Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);
image = image.GetThumbnailImage(200, 200, myCallback, IntPtr.Zero);
}
context.Response.ContentType = "image/png";
// Save the image to the OutputStream
image.Save(context.Response.OutputStream, ImageFormat.Png);
} }
Thanks.
Probably for the same reason that this guy was having problems - because the for a lifetime of an Image constructed from a Stream, the stream must not be destroyed.
So if your GetImage function constructs the returned image from a stream (e.g. a MemoryStream) and then closes the stream before returning the image then the above will fail. My guess is that your GetImage looks a tad like this:
Image GetImage(int id)
{
byte[] data = // Get data from database
using (MemoryStream stream = new MemoryStream(data))
{
return Image.FromStream(data);
}
}
If this is the case then try having GetImage return the MemoryStream (or possibly the byte array) directrly so that you can create the Image instance in your ProcessRequest method and dispose of the stream only when the processing of that image has completed.
This is mentioned in the documentation but its kind of in the small print.

Resources