Load CCSprite Image from URL - CocosSharp + Xamarin.forms - xamarin

I am working on Xamarin.Forms + CocosSharp Application. Here I want to load an image from an URL in cocoassharp using CCSprite. How can I achieve this? Normal CCSprite image is created like: var sprite = new CCSprite("image.png");

It is better to use async for stream and Read. I just did testing in place where that was not convenient but you should use async versions.
var webClient = new HttpClient();
var imageStream = webClient.GetStreamAsync(new Uri("https://xamarin.com/content/images/pages/forms/example-app.png")).Result;
byte[] imageBytes = new byte[imageStream.Length];
int read=0;
do
{
read += imageStream.Read(imageBytes, read, imageBytes.Length- read);
} while (read< imageBytes.Length);
CCTexture2D texture = new CCTexture2D(imageBytes);
var sprite = new CCSprite(texture);

Related

How to load/draw an image using NGraphics?

In my Xamarin Forms app, I have an image under androidProject/Resources/drawable/myImage.png. To load these from Xamarin, you can simply do
Image myImage = new Image() { Source = ImageSource.FromFile("myImage.png") };
However, there is no way to draw an Image using NGraphics. Instead, NGraphics DrawImage(IImage) requires an IImage. As far as I can tell, there's no way to turn a Xamarin.Forms.Image into an NGraphics.IImage. In fact, the only way I could find to load IImage is
IImage myImage = Platform.LoadImage("myImage.png");
However, this doesn't work because under the hood this uses BitmapFactory.decodeFile(), which requires the absolute file path. And I couldn't find any way to get the absolute file path of a resource (if it even exists?)
So, how do I actually load and display an image using NGraphics?
NGraphics does not provide any helpers to load images from your Platforms Resource files.
You could do something as follows. However, it will add some overhead converting back and forth between bitmap -> stream -> bitmap.
Android:
Stream GetDrawableStream(Context context, int resourceId)
{
var drawable = ResourcesCompat.GetDrawable(context.Resources, resourceId, context.Theme);
if (drawable is BitmapDrawable bitmapDrawable)
{
var stream = new MemoryStream();
var bitmap = bitmapDrawable.Bitmap;
bitmap.Compress(Bitmap.CompressFormat.Png, 80, stream);
bitmap.Recycle();
return stream;
}
return null;
}
iOS:
Stream GetImageStream(string fileName)
{
using (var image = UIImage.FromFile(fileName))
using (var imageData = image.AsPNG())
{
var byteArray = new byte[imageData.Length];
System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, byteArray, 0, Convert.ToInt32(imageData.Length));
var stream = new MemoryStream(byteArray);
return stream;
}
return null;
}
However, you could go directly from Bitmap to BitmapImage on Android instead like:
BitmapImage GetBitmapFromDrawable(Context context, int resourceId)
{
var drawable = ResourcesCompat.GetDrawable(context.Resources, resourceId, context.Theme);
if (drawable is BitmapDrawable bitmapDrawable)
{
var bitmap = bitmapDrawable.Bitmap;
return new BitmapImage(bitmap);
}
return null;
}
And on iOS:
CGImageImage GetImageStream(string fileName)
{
var iOSimage = UIImage.FromFile(fileName);
var cgImage = new CGImageImage(iOSImage.CGImage, iOSImage.Scale);
return cgImage;
}
BitmapImage and CGImageImage implement IImage in NGraphics.

Why is image very Dark with AVCaptureSession

We have Xamarin Forms solution and in iOS project we are trying to create photo on button click. Problem is image is very dark. It is almost black. Why is this happening? Here is a code:
var _captureSession = new AVCaptureSession();
var _captureDevice = AVCaptureDevice.GetDefaultDevice(AVMediaType.Video);
var _captureDeviceInput = AVCaptureDeviceInput.FromDevice(_captureDevice);
_captureSession.AddInput(_captureDeviceInput);
_captureSession.StartRunning();
private async void OnButtonClick()
{
var output = new AVCaptureStillImageOutput { OutputSettings = new NSDictionary(AVVideo.CodecKey, AVVideo.CodecJPEG) };
_captureSession.AddOutput(output);
var buffer = await output.CaptureStillImageTaskAsync(output.Connections[0]);
NSData data = AVCaptureStillImageOutput.JpegStillToNSData(buffer);
UIImage image = UIImage.LoadFromData(data);
//image = RotateImage(image);
NSData imageData = image.AsPNG();
byte[] byteArray = imageData.ToArray();
IFolder folder = FileSystem.Current.LocalStorage;
IFile file = await folder.CreateFileAsync("image.png", CreationCollisionOption.ReplaceExisting);
using (Stream stream = await file.OpenAsync(PCLStorage.FileAccess.ReadAndWrite))
{
stream.Write(image, 0, image.Length);
}
}
Here is image:
Line:
_captureSession.AddOutput(output);
should go before button click (before StartRunning). With that change image has normal brightness and also rotation is not needed.

Get image from signaturepad in xamarin forms?

After downloading xamarin.signaturePad sample i just want to get image from signature pad to memory stream and show on my imageview. here is my code and its working fine on iOS but on android its showing empty stream
var image = await padView.GetImageStreamAsync(SignatureImageFormat.Png);
var stream = new MemoryStream();
image.CopyToAsync(stream);
var imageByteArray= stream.ToArray();
img_result.Source = ImageSource.FromStream(() => newMemoryStream(imageByteArray));
Just cast your imagestream to memorystream. It should be valid
var imageStream = await padView.GetImageStreamAsync(SignatureImageFormat.Png);
// this is actually memory-stream so convertible to it
var mstream = (MemoryStream)imageStream;
//Unfortunately above mstream is not valid until you take it as byte array
mstream = new MemoryStream(mstream.ToArray());
//Now you can
img_result.Source = ImageSource.FromStream(()=>mstream);

nokia Imaging SDK customize BlendFilter

I have created this code
Uri _blendImageUri = new Uri(#"Assets/1.png", UriKind.Relative);
var _blendImageProvider = new StreamImageSource((System.Windows.Application.GetResourceStream(_blendImageUri).Stream));
var bf = new BlendFilter(_blendImageProvider);
Filter work nice. But I want change image size for ForegroundSource property. How can I load image with my size?
If I understood you correctly you are trying to blend ForegroundSource with only a part of the original image? That is called local blending at it is currently not supported on the BlendFilter itself.
You can however use ReframingFilter to reframe the ForegroundSource and then blend it. Your chain will look like something like this:
using (var mainImage = new StreamImageSource(...))
using (var filterEffect = new FilterEffect(mainImage))
{
using (var secondaryImage = new StreamImageSource(...))
using (var secondaryFilterEffect = new FilterEffect(secondaryImage))
using (var reframing = new ReframingFilter(new Rect(0, 0, 500, 500), 0)) //reframe your image, thus "setting" the location and size of the content when blending
{
secondaryFilterEffect.Filters = new [] { reframing };
using (var blendFilter = new BlendFilter(secondaryFilterEffect)
using (var renderer = new JpegRenderer(filterEffect))
{
filterEffect.Filters = new [] { blendFilter };
await renderer.RenderAsync();
}
}
}
As you can see, you can use the reframing filter to position the content of your ForegroundSource so that it will only blend locally. Note that when reframeing you can set the borders outside of the image location (for example new Rect(-100, -100, 500, 500)) and the areas outside of the image will appear as black transparent areas - exactly what you need in BlendFilter.

MediaLibrary.SavePicture method results in a System.UnauthorizedAccessException

I've got the following code which handles downloading and saving an Image to the phone's media library. It fails with a System.UnauthorizedAccessException as if there was some cross-thread access. To my understading all code below an await statement runs on the UI thread so this should not be an issue. In addition I've tried wrapping the code below var stream = await client.OpenReadTaskAsync(this.Url); with Deployment.Current.Dispatcher.BeginInvoke but it did not help. :(
I am running this on WP8 with the intention to port the code later to WP7.
private async void OnSaveImageCommand()
{
RunProgressIndicator(true, "Downloading image...");
var client = new WebClient();
try
{
var stream = await client.OpenReadTaskAsync(this.Url);
var bitmap = new BitmapImage();
bitmap.SetSource(stream);
using (var memoryStream = new MemoryStream())
{
var writeableBitmap = new WriteableBitmap(bitmap);
writeableBitmap.SaveJpeg(memoryStream, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight, 0,
100);
memoryStream.SetLength(memoryStream.Position);
memoryStream.Seek(0, SeekOrigin.Begin);
var mediaLibrary = new MediaLibrary();
mediaLibrary.SavePicture("image.jpg", memoryStream);
MessageBox.Show("Image has been saved to the phone's photo album");
}
}
catch
{
MessageBox.Show("Failed to download image");
}
finally
{
RunProgressIndicator(false);
}
}
Did you add an ID_CAP_MEDIALIB_PHOTO capability to your app's manifest?
UnauthorizedAccessException is 99% of the time a missing capability.

Resources