I want to load an image from url to imageview in c# ( android programming ) after search in google i cant find any good result , thank you for helping
i am using xamarin studio
The very first hit I got from Google was a thread on the Xamarin forums discussing this exact issue:
private Bitmap GetImageBitmapFromUrl(string url)
{
Bitmap imageBitmap = null;
using (var webClient = new WebClient())
{
var imageBytes = webClient.DownloadData(url);
if (imageBytes != null && imageBytes.Length > 0)
{
imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
}
}
return imageBitmap;
}
var imageBitmap = GetImageBitmapFromUrl("http://xamarin.com/resources/design/home/devices.png");
imagen.SetImageBitmap(imageBitmap);
Both approaches work, but is a good practice to do it asynchronously. Here you have some good examples:
Asynchronous Image Loading in Xamarin Android http://javatechig.com/xamarin/asynchronous-image-loading-xamarin-android
xamarin-store-app image helper https://github.com/xamarin/xamarin-store-app/blob/master/XamarinStore.Droid/Helpers/Images.cs
Am using the below class in Xamarin Android:
public class DownloadImageTask : AsyncTask
{
private ImageView bmImage;
private ProgressBar progressBar;
public DownloadImageTask( ImageView bmImage , ProgressBar progressBar)
{
this.bmImage = bmImage;
this.progressBar = progressBar;
}
protected override void OnPostExecute( Object result )
{
base.OnPostExecute(result);
bmImage.SetImageBitmap(( Bitmap ) result);
if (progressBar != null)
progressBar.Visibility = ViewStates.Gone;
}
protected override Object DoInBackground( params Object[] #params )
{
var urldisplay = #params[0].ToString();
Bitmap mIcon11 = null;
try
{
var req = WebRequest.Create(urldisplay);
var response = req.GetResponse();
var stream = response.GetResponseStream();
mIcon11 = BitmapFactory.DecodeStream(stream);
}
catch ( Exception e )
{
}
return mIcon11;
}
}
Execution :
new DownloadImageTask(imgProfile , progressBar).Execute(uri);
I did this to load an Svg from an url into an ImageView using SkiaSharp.
In the .xml
<ImageView
android:contentDescription=""
android:id="#+id/video_recorder_image"
android:layout_width="wrap_content"
android:layout_height="50dp" />
In the activity/fragment.
private ImageView iconImageView;
public override void OnViewCreated(View view, Bundle savedInstanceState)
{
iconImageView = (ImageView)view.FindViewById(Resource.Id.video_recorder_image);
Bitmap image = GetImageBitmapFromUrl(_iconUrl);
}
private Bitmap GetImageBitmapFromUrl(string url)
{
Bitmap imageBitmap = null;
using (var webClient = new WebClient())
{
var imageBytes = webClient.DownloadData(url);
if (imageBytes != null && imageBytes.Length > 0)
{
var svgContent = Convert.ToBase64String(imageBytes, 0, imageBytes.Length);
var byteArray = Convert.FromBase64String(svgContent);
using (var stream = new MemoryStream(byteArray))
{
var bitmap = new SKBitmap(500, 500);
var canvas = new SKCanvas(bitmap);
// load the SVG
var svg = new SkiaSharp.Extended.Svg.SKSvg(new SKSize(500, 500));
svg.Load(stream);
// draw the SVG to the bitmap
canvas.DrawPicture(svg.Picture);
var skData = SKImage.FromBitmap(bitmap).Encode(SKEncodedImageFormat.Png, 100);
// Convert image to string and then to Bitmap
var convertedSvgStream = skData.AsStream();
var convertedImageBytes = new byte[(int)convertedSvgStream.Length];
convertedSvgStream.Seek(0, SeekOrigin.Begin);
convertedSvgStream.Read(convertedImageBytes, 0, (int)convertedSvgStream.Length);
imageBitmap = BitmapFactory.DecodeByteArray(convertedImageBytes, 0, convertedImageBytes.Length);
}
}
}
return imageBitmap;
}
Related
Is there a package that does screen capture in xamarin.forms ?
I need also to capture google maps screen shots
Check out this blog post by Daniel Hindrikes.
I'm going to assume that you use a PCL for your shared code.
You will need to create an interface in your PCL. He calls it IScreenshotManager. The declaration looks like this:
public interface IScreenshotManager
{
Task<byte[]> CaptureAsync();
}
Now all platforms will have their own implementation for it.
For iOS;
public class ScreenshotManager : IScreenshotManager
{
public async System.Threading.Tasks.Task<byte[]> CaptureAsync()
{
var view = UIApplication.SharedApplication.KeyWindow.RootViewController.View;
UIGraphics.BeginImageContext(view.Frame.Size);
view.DrawViewHierarchy(view.Frame, true);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
using(var imageData = image.AsPNG())
{
var bytes = new byte[imageData.Length];
System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, bytes, 0, Convert.ToInt32(imageData.Length));
return bytes;
}
}
}
For Android:
public class ScreenshotManager : IScreenshotManager
{
public static Activity Activity { get; set; }
public async System.Threading.Tasks.Task<byte[]> CaptureAsync()
{
if(Activity == null)
{
throw new Exception("You have to set ScreenshotManager.Activity in your Android project");
}
var view = Activity.Window.DecorView;
view.DrawingCacheEnabled = true;
Bitmap bitmap = view.GetDrawingCache(true);
byte[] bitmapData;
using (var stream = new MemoryStream())
{
bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
bitmapData = stream.ToArray();
}
return bitmapData;
}
}
And for Windows Phone:
public class ScreenshotManager : IScreenshotManager
{
public async Task<byte[]> CaptureAsync()
{
var rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
var screenImage = new WriteableBitmap((int)rootFrame.ActualWidth, (int)rootFrame.ActualHeight);
screenImage.Render(rootFrame, new MatrixTransform());
screenImage.Invalidate();
using (var stream = new MemoryStream())
{
screenImage.SaveJpeg(stream, screenImage.PixelWidth, screenImage.PixelHeight, 0, 100);
var bytes = stream.ToArray();
return bytes;
}
}
}
Don't forget to register your platform specific implementations with the attribute which registers it with the Dependency Service, like this:
[assembly: Xamarin.Forms.Dependency (typeof (ScreenshotManager))]
It goes above the namespace declaration.
Now from your shared code you would be able to get the byte[] of a screenshot with a call like this:
var screenshotBytes = DependencyService.Get<IScreenshotManager>().CaptureAsync();
You probably want to check if DependencyService.Get<IScreenshotManager>() isn't null before using it.
After that you can turn your byte[] into an image and do whatever you like with it!
Implementation for UWP
public async Task<byte[]> CaptureAsync()
{
//create and capture Window
var renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(Window.Current.Content);
var pixelpuffer = await renderTargetBitmap.GetPixelsAsync();
var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
IRandomAccessStream stream = new InMemoryRandomAccessStream();
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, logicalDpi, logicalDpi, pixelpuffer.ToArray());
await encoder.FlushAsync();
byte[] resultingBuffer = new byte[stream.Size];
await stream.ReadAsync(resultingBuffer.AsBuffer(), (uint)resultingBuffer.Length, InputStreamOptions.None);
return resultingBuffer;
}
I'm a beginner in Xamarin.Forms, and I have a question: How can I call the following code in my shared code/xaml.cs?
public class screenshotManager : IScreenshotManager
{
public static Activity Activity { get; set; }
public async System.Threading.Tasks.Task<byte[]> CaptureAsync()
{
if (Activity == null)
{
throw new Exception("You have to set ScreenshotManager.Activity in your Android project");
}
var view = Activity.Window.DecorView;
view.DrawingCacheEnabled = true;
Bitmap bitmap = view.GetDrawingCache(true);
byte[] bitmapData;
using (var stream = new MemoryStream())
{
bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
bitmapData = stream.ToArray();
}
return bitmapData;
}
}
If your need is to get the image captured from a byte[], as we discussed in comments, so you should do as #Jason said.
Something like this:
var imageBytes = await screenshotManager.CaptureAsync();
Image imageView = new Image();
imageView.Source = ImageSource.FromStream(() => new MemoryStream(imageBytes));
I need to render svg in my XSL fo in c#.Net which is available in https://fonet.codeplex.com/. I tried to use svg in the xsl-fo but it does not render any pdf and fails silently.
If anybody has found a solution for this issue please help.
I need my pdf report to support svg contents.
Use the below code to add Hander of an image incase of svg extensions
FonetDriver fonetDriver = FonetDriver.Make();
fonetDriver.ImageHandler = SvgImageHandler;
Add the SvgImageHandler Hander
private static byte[] SvgImageHandler(string svgContent)
{
if (svgContent.Contains("http://www.w3.org/2000/svg"))
{
var svgByteAry = Encoding.UTF8.GetBytes(svgContent);
using (var stream = new MemoryStream(svgByteAry))
{
var svgDocument = SvgDocument.Open<SvgDocument>(stream);
using (var memoryStream = new MemoryStream())
{
svgDocument.Draw()
.Save(memoryStream, ImageFormat.Png);
var byteArray = memoryStream.ToArray();
return byteArray;
}
}
}
//Skip if not url based image
if (!Uri.IsWellFormedUriString(svgContent, UriKind.RelativeOrAbsolute))
return null;
if (!ValidateUrlImage(svgContent))
{
ICacheService cacheService = new HttpCache();
return cacheService.Get(Constants.NoImage,
() =>
{
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings[Constants.ImagePath];
var defaultUrl = Path.Combine(baseDirectory, Constants.NoImageFile);
var img = Image.FromFile(defaultUrl);
var imgCon = new ImageConverter();
return (byte[])imgCon.ConvertTo(img, typeof(byte[]));
});
}
return null;
}
Return proper image if the url is valid or pass false so the No Image can be rendered. keeping the code more robust.
private static bool ValidateUrlImage(string absoluteUrl)
{
Uri uri;
if (!Uri.TryCreate(absoluteUrl, UriKind.Absolute, out uri))
{
return true;
}
using (var client = new WebClient())
{
try
{
using (var stream = client.OpenRead(uri))
{
Image.FromStream(stream);
return true;
}
}
catch (Exception)
{
return false;
}
}
}
I'm unsure on how I can go from WriteAbleBitmap to IconicTileData's url property IconImage.
Here is my code so far:
protected override void OnInvoke(ScheduledTask task)
{
ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault();
if (tile != null)
{
WriteableBitmap genTile = renderTile(202, 202);
tile.Update(new IconicTileData()
{
Title = "IconicTileData",
IconImage = /* PATH TO genTile */
});
}
ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(3));
NotifyComplete();
}
private WriteableBitmap renderTile(int width, int height)
{
Canvas can = new Canvas();
can.Background = new SolidColorBrush(Color.FromArgb(255, 0, 255, 0));
can.Width = width;
can.Height = height;
WriteableBitmap tileImage = new WriteableBitmap(width, height);
tileImage.Render(can, null);
tileImage.Invalidate();
return tileImage;
}
The solution would be to save the file? How can I do that, ShellTile does not share the same space as the application?
Save the file to isolated storage, and then use the "isostore:" prefix in the Uri.
public static void StoreSavedResultImage(string filename, WriteableBitmap wb)
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isf.FileExists(filename))
isf.DeleteFile(filename);
using (IsolatedStorageFileStream fs = isf.CreateFile(filename))
{
wb.SaveJpeg(fs, wb.PixelWidth, wb.PixelHeight, 0, 100);
fs.Close();
wb = null;
img = null;
}
}
}
If you want to reference a file from isolated storage in a live tile, the file should be saved in the /Shared/ShellContent folder.
Uri wideUri = new Uri("isostore:/Shared/ShellContent/app_wide.jpg"), UriKind.Absolute);
tile.Update(new IconicTileData()
{
Title = "IconicTileData",
IconImage = wideUri
});
Hi I would like download images from web asychrounly in parallel loop foreach.
I have dictionary with signature IDictionary<string,user>.
User class has two properties:
Uri ProfilePhoto
BitmapImage ProfilePhotoAsBitmapImage
My aim is, go through dictionary in loop if ProfilePhoto is null I get default avatar, it not I would like download image from web asynchronly.
private void GetProfilePhotosFromServer(IEnumerable<UserInfo> friends)
{
Parallel.ForEach(friends, f =>
{
//get defualt
if (f.ProfilePhoto == null)
f.ProfilePhotoAsBitmap = CreateDefaultAvatar(f.Sex);
//start downloading from web server asynchronly
//problem is that I don’t know how retrieve BitmapImage object from
//StartDownloading method or method ProcessImage, which is on the bottom
//of my question
var image = StartDownloadingImage(f.MediumProfilePhoto);
image.Freeze();
f.ProfilePhotoAsBitmap = image;
});
}
Problem is that I don’t know how retrieve BitmapImage object from StartDownloading method or method ProcessImage, which is on the bottom of my question.
Start web request:
private void StartDownloadingImage(Uri imageUri)
{
_webRequest = WebRequest.Create(imageUri);
_webRequest.BeginGetResponse(this.ProcessImage, null);
//how retrieve result of ProcessImage method
}
After web request is finished I call this method:
private void ProcessImage(IAsyncResult asyncResult)
{
var response = _webRequest.EndGetResponse(asyncResult);
using (var stream = response.GetResponseStream())
{
var buffer = new Byte[response.ContentLength];
int offset = 0, actuallyRead = 0;
do
{
actuallyRead = stream.Read(buffer, offset, buffer.Length - offset);
offset += actuallyRead;
}
while (actuallyRead > 0);
var image = new BitmapImage
{
CreateOptions = BitmapCreateOptions.None,
CacheOption = BitmapCacheOption.OnLoad
};
image.BeginInit();
image.StreamSource = new MemoryStream(buffer);
image.EndInit();
//problem
return image;
}
}
BitmapImage object is created in ProcessImage method how can I pass this object to the property od User object which is used in GetProfilePhotosFromServer method?
Method above create from MemoryStream BitampImage object.
You need to pass in the additional operations and the UserInfo object as a callback to the asynchronous method. The easiest way to do this is to create a class containing them and pass that as the asynchronous state of the method.
private class ImageCallbackState
{
public UserInfo Friend { get; set; }
public Action<UserInfo,BitmapImage> Callback { get; set; }
}
private void GetProfilePhotosFromServer(IEnumerable<UserInfo> friends)
{
Parallel.ForEach(friends, f =>
{
//get defualt
if (f.ProfilePhoto == null)
f.ProfilePhotoAsBitmap = CreateDefaultAvatar(f.Sex);
Action<UserInfo,BitmapImage> action = (u,i) => {
i.Freeze();
u.ProfilePhotoAsBitMap = i;
};
var state = new ImageCallbackState { Friend = f, Callback = action };
StartDownloadingImage(f.MediumProfilePhoto,state);
});
}
private void StartDownloadingImage(Uri imageUri, ImageCallbackState state)
{
_webRequest = WebRequest.Create(imageUri);
_webRequest.BeginGetResponse(this.ProcessImage, state); // pass callback state
}
private void ProcessImage(IAsyncResult asyncResult)
{
var response = _webRequest.EndGetResponse(asyncResult);
using (var stream = response.GetResponseStream())
{
var buffer = new Byte[response.ContentLength];
int offset = 0, actuallyRead = 0;
do
{
actuallyRead = stream.Read(buffer, offset, buffer.Length - offset);
offset += actuallyRead;
}
while (actuallyRead > 0);
var image = new BitmapImage
{
CreateOptions = BitmapCreateOptions.None,
CacheOption = BitmapCacheOption.OnLoad
};
image.BeginInit();
image.StreamSource = new MemoryStream(buffer);
image.EndInit();
var state = asyncResult.AsyncState as ImageCallbackState
state.Callback(state.Friend,image);
}
}