Hello the app that I'm building works with alot of images that are stored on the server and need to display them on a listview. I would like to be able to store them on a file.
so far here is the code I have
var imageUrl = new Java.Net.URL(obj.imageUrl);
var bitmap = Android.Graphics.BitmapFactory.DecodeStream(imageUrl.OpenStream());
var image = new Android.Graphics.Drawables.BitmapDrawable(bitmap);
but I don't know how to save the image or where to save it.
any help?
thanks
You're overthinking this. :-)
Once you have a Stream:
var imageUrl = new Java.Net.URL(obj.imageUrl);
System.IO.Stream stream = imageUrl.OpenStream();
you can just save it to disk:
using (var o = File.Open(
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),
"file-name"))) {
byte[] buf = new byte[1024];
int r;
while ((r = stream.Read(buf, 0, buf.Length)) > 0)
o.Write (buf, 0, r);
}
Environment.GetFolderPath(Environment.SpecialFolder.Personal) returns $APPDIR/files, which is Context.FilesDir. You don't necessarily need to use this; Context.CacheDir may be more appropriate.
Related
I have been trying to make an application that invokes camera through page rendering. I have used Custom Renderer from Xamarin. My problem is I need to send the picture to the other page/activity in the "Native" after clicking, but currently it is saving the picture in the gallery of the device.
For example: I click the image and then the image gets displayed with the message "Do you want to save it?". This has to be done in native rather than PCL. I have been trying through intent but that doesn't work.
All my code right now doing is saving the image to the gallery.
try
{
var absolutePath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim).AbsolutePath;
var folderPath = absolutePath + "/Camera";
var filePath = System.IO.Path.Combine(folderPath, string.Format("photo_{0}.jpg", Guid.NewGuid()));
var fileStream = new FileStream(filePath, FileMode.Create);
await image.CompressAsync(Bitmap.CompressFormat.Jpeg, 100, fileStream);
fileStream.Close();
image.Recycle();
// imageByte = ((byte[])image);
var intent = new Android.Content.Intent(Android.Content.Intent.ActionMediaScannerScanFile);
var file = new Java.IO.File(filePath);
var uri = Android.Net.Uri.FromFile(file);
intent.SetData(uri);
//intent.PutExtra("image", imageByte);
MainActivity.Instances.SendBroadcast(intent);
}
Solved it. Passing bitmap through intent.
Activity 1:
byte[] imageByte;
var image = textureView.Bitmap;
MemoryStream memStream = new MemoryStream();
// ByteArrayOutputStream _bs = new ByteArrayOutputStream();
await image.CompressAsync(Bitmap.CompressFormat.Jpeg, 100, memStream);
imageByte = memStream.ToArray();
Intent i = new Intent(this.Context, typeof(CameraDisplay));
i.PutExtra("image", imageByte);
activity.StartActivity(i);
Activity 2:
byte[] Image = Intent.GetByteArrayExtra("image");
imageView = FindViewById(Resource.Id.imageView1);
Bitmap bitmap = BitmapFactory.DecodeByteArray(Image, 0, Image.Length);
imageView.SetImageBitmap(bitmap);
I need to make a GET request that requires oauth, for and image to display in a page. Is there a way to do this without building a custom webrequest or httpwebrequest?
If it's an image make sure that you are reading the stream as binary data.
Something like:
var httpRequest = (HttpWebRequest)ar.AsyncState;
var httpResponse = (HttpWebResponse)httpRequest.EndGetResponse(ar);
int lengthInBytes = Convert.ToInt32(httpResponse.ContentLength);
BinaryReader br = new BinaryReader(httpResponse.GetResponseStream());
byte[] imageInBytes = new byte[lengthInBytes];
using (br)
{
for (int i = 0; i < lengthInBytes; i++)
{
imageInBytes[i] = br.ReadByte();
}
}
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
MemoryStream rawBytesStream = new MemoryStream(imageInBytes);
BitmapImage img = new BitmapImage();
img.SetSource(rawBytesStream);
imageInUI.Source = img;
});
I'm having a really interesting problem to solve:
I'm getting a static google map image, with an URL like this.
I've tried several methods to get this information:
Fetching the "remote resource" as a ByteArrayOutputStream, storing the Image in the SD of the Simulator, an so on... but every freaking time I get an IlegalArgumentException.
I always get a 200 http response, and the correct MIME type ("image/png"), but either way: fetching the image and converting it to a Bitmap, or storing the image in the SD and reading it later; I get the same result... the file IS always corrupt.
I really belive its an encoding problem, or the reading method (similar to this one):
public static Bitmap downloadImage(InputStream inStream){
byte[] buffer = new byte[256];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (inStream.read(buffer) != -1){
baos.write(buffer);
}
baos.flush();
baos.close();
byte[] imageData = baos.toByteArray();
Bitmap bi = Bitmap.createBitmapFromBytes(imageData, 0, imageData.length, 1);
//Bitmap bi = Bitmap.createBitmapFromBytes(imageData, 0, -1, 1);
return bi;
}
The only thing that comes to mind is the imageData.lenght (in the response, the content length is: 6005 ), but I really can't figure this one out.
Any help is more than welcome...
try this way:
InputStream input = httpConn.openInputStream();
byte[] xmlBytes = new byte[256];
int len = 0;
int size = 0;
StringBuffer raw = new StringBuffer();
while (-1 != (len = input.read(xmlBytes)))
{
raw.append(new String(xmlBytes, 0, len));
size += len;
}
value = raw.toString();
byte[] dataArray = value.getBytes();
EncodedImage bitmap;
bitmap = EncodedImage.createEncodedImage(dataArray, 0,dataArray.length);
final Bitmap googleImage = bitmap.getBitmap();
Swati's answer is good. This same thing can be accomplished with many fewer lines of code:
InputStream input = httpConn.openInputStream();
byte[] dataArray = net.rim.device.api.io.IOUtilities.streamToBytes(input);
Bitmap googleImage = Bitmap.createBitmapFromBytes(dataArray, 0, -1, 1);
In Windows Phone 7 how can I save a BitmapImage to local storage? I need to save the image for caching and reload if it is requested again in the next few days.
If you save the file into IsolatedStorage you can set a relative path to view it from there.
Here's a quick example saving a file that was included in the XAP (as a resource) into Isolated Storage.
using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!isoStore.FileExists(fileName)
{
var sr = Application.GetResourceStream(new Uri(fileName, UriKind.Relative));
using (var br = new BinaryReader(sr.Stream))
{
byte[] data = br.ReadBytes((int)sr.Stream.Length);
string strBaseDir = string.Empty;
const string DelimStr = "/";
char[] delimiter = DelimStr.ToCharArray();
string[] dirsPath = fileName.Split(delimiter);
// Recreate the directory structure
for (int i = 0; i < dirsPath.Length - 1; i++)
{
strBaseDir = Path.Combine(strBaseDir, dirsPath[i]);
isoStore.CreateDirectory(strBaseDir);
}
using (BinaryWriter bw = new BinaryWriter(isoStore.CreateFile(fileName)))
{
bw.Write(data);
}
}
}
}
You may also be interested in the image caching converters created by Ben Gracewood and Peter Nowaks. They both show saving images into isolated storage and loading them from there.
Another approach I've used is to pass the stream you retrieve for the image in your xap straight into an isolated storage file. Not a lot of moving parts.
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication()) {
var bi = new BitmapImage();
bi.SetSource(picStreamFromXap);
var wb = new WriteableBitmap(bi);
using (var isoFileStream = isoStore.CreateFile("pic.jpg"))
Extensions.SaveJpeg(wb, isoFileStream, wb.PixelWidth, wb.PixelHeight, 0, 100);
}
I use the following code to retrieve image from the phone or SDCard and I use that image in to my ListField. It gives the output but it takes very Long time to produce the screen. How to solve this problem ?? Can any one help me?? Thanks in advance!!!
String text = fileholder.getFileName();
try{
String path="file:///"+fileholder.getPath()+text;
//path=”file:///SDCard/BlackBerry/pictures/image.bmp”
InputStream inputStream = null;
//Get File Connection
FileConnection fileConnection = (FileConnection) Connector.open(path);
inputStream = fileConnection.openInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int j = 0;
while((j=inputStream.read()) != -1) {
baos.write(j);
}
byte data[] = baos.toByteArray();
inputStream.close();
fileConnection.close();
//Encode and Resize image
EncodedImage eImage = EncodedImage.createEncodedImage(data,0,data.length);
int scaleFactorX = Fixed32.div(Fixed32.toFP(eImage.getWidth()),
Fixed32.toFP(180));
int scaleFactorY = Fixed32.div(Fixed32.toFP(eImage.getHeight()),
Fixed32.toFP(180));
eImage=eImage.scaleImage32(scaleFactorX, scaleFactorY);
Bitmap bitmapImage = eImage.getBitmap();
graphics.drawBitmap(0, y+1, 40, 40,bitmapImage, 0, 0);
graphics.drawText(text, 25, y,0,width);
}
catch(Exception e){}
You should read files once (on App start or before screen open, maybe put a progress dialog there), put images in array and use this array in paint.