Xamarin: CGImageSource.FromUrl returning null - xamarin

I am using the following code in my application.
string imageUrl = "https://imageUrl.png/"; //This is a valid url. I can see the image when I paste the url into my web browser
var url = new NSUrl(imageUrl);
using (CGImageSource source = CGImageSource.FromUrl(url))
{
if (source != null)
{
//I never get here
}
}
Why is source always null? I've tried many different imageUrls, all with the same result.

Your photo address seems to be HTTPS prefix.which is different from HTTP.You can try another URL be HTTP prefix.If the address must be HTTPS,I suggest you use some SDK.
or you can use the following code,they works when use http
string str = ""; //your image url
NSData ImageData = NSData.FromUrl(new NSUrl(str) );
UIImage image = new UIImage(ImageData);
if (image != null)
{
Console.Write("success");
}
else
{
Console.Write("fail");
}

Related

bannerview.ad unit is obsolete: use adunitid property instead

I'm trying to archive my iOS app and problem shows to me because of Google Mobile Ads .
bannerview.adunit is obsolete: use adunitid property instead
I'm trying to find solution to it
private BannerView CreateBannerView()
{
if (_bannerView != null)
return _bannerView;
var origin = new CGPoint(0, UIScreen.MainScreen.Bounds.Size.Height - AdSizeCons.Banner.Size.Height);
_bannerView = new BannerView(AdSizeCons.SmartBannerPortrait, origin)
{
AdUnitID = Element.AdUnitId,
RootViewController = GetVisibleViewController()
};
_bannerView.LoadRequest(GetRequest());
return _bannerView;
}
private Request GetRequest()
{
var request = Request.GetDefaultRequest();

Drag an image from table cell to an iFrame droppable area

I have problems to drag an image from one iframe (1) out of a dynamic table to another iframe (2) within a droppable area. I think there is no permission issue, but a "type" issue. The drop area on iframe (2) is working with files from anywhere except form the iframe (1). The iframe (1) is hosted by localhost. The iframe (2) is hosted by a different domain.
Three different functions I found to convert data uri to file or blob were tested. The setData arguments also have been tested with all possibilities, no success by now.
Interestingly, having opened the site with the two iframes on Chrome and firefox, I am able to drag an drop from firefox to Chrome, but the image will be converted to bmp type and renamed! The other way around it is not working.
What are the right arguments for setData / get Data to drop an image
data uri on a drop area?
Do I have to convert data uri to a file
resp. blob object?
If so, again, what arguments will do the job?
Any help would be appreciated very much!
var dataUri;
var file;
function mouseDown(event){
toDataURL(event.target.src, function(dataUrl) {
console.log('RESULT:', dataUrl.replace('data:text/plain;base64,', ''));
dataUri = dataUrl.replace('data:text/plain;base64,', '');
file = urltoFile(dataUrl, 'hello.jpg','image/jpeg')
.then(function(file){ console.log(file);});
})
}
function drag(event) {
// event.stopPropagation();
console.log(file);
console.log(dataUri);
event.dataTransfer.setData("text/plain", file);
//event.dataTransfer.mozSetDataAt("application/x-moz-file", file, 0);
event.dataTransfer.effectAllowed = "move";
}
function drop(event) {
//event.preventDefault();
console.log(file);
console.log(dataUri);
var data = event.dataTransfer.getData("text/plain");
//var data = event.dataTransfer.mozGetDataAt("application/x-moz-file", 0);
event.target.appendChild(document.getElementById(data));
document.getElementsById(data);
console.log(data);
}
function allowDrop(event) {
event.preventDefault();
}
function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type:mime});
}
function urltoFile(url, filename, mimeType){
return (fetch(url)
.then(function(res){return res.arrayBuffer();})
.then(function(buf){return new File([buf], filename,{type:mimeType});})
);
}
function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var dw = new DataView(ab);
for(var i = 0; i < byteString.length; i++) {
dw.setUint8(i, byteString.charCodeAt(i));
}
// write the ArrayBuffer to a blob, and you're done
return new Blob([ab], {type: mimeString});
}

Download Photo not saved on local folder Xamarin Forms iOS

Saved image not showing on galary iOS(working fine on Android but not iOS)
Here is my code for saving image to device
public void SavePicture(string name, byte[] data, string location = "Downloads")
{
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
documentsPath = Path.Combine(documentsPath, location);
Directory.CreateDirectory(documentsPath);
string filePath = Path.Combine(documentsPath, name);
File.WriteAllBytes(filePath, data); // writes to local storage
}
Also allow for photo permission on info.plist
Privacy - Photo Library Usage Description
after execute this code I cant find the saved photo on iOS device
How to solve this?
Well in iOS to show an image into the gallery you have to write additional code as just using File.WriteAllBytes won't call the native UIImageWriteToSavedPhotosAlbum API to show it in the album.
To do that you will have to call this API as follows:
Make a dependency service:
public interface ISavePhotosToAlbum
{
void SavePhotosWithFilePath(String Path);
}
Now Add a native class and do the following:
[assembly: Dependency(typeof(SaveToAlbum))]
namespace SavePhotosDemo.iOS
{
public class SaveToAlbum : ISavePhotosToAlbum
{
public void SavePhotosWithFilePath(String Path)
{
using (var url = new NSUrl (Path))
using (var data = NSData.FromUrl (url))
var image = UIImage.LoadFromData (data);
image.SaveToPhotosAlbum((img, error) =>
{
if (error == null)
{//Success }
else
{//Failure}
});
}
}
}
Then use this Dependency Service as follows:
DependencyService.Get<ISavePhotosToAlbum>().SavePhotosWithStream(imageUrl);
Also, see to it that you add this dependency service call only for ios by adding it in an OnPlatform if statement.
UPDATE
Use the following code to Add a Custom Photo Album in Photos library:
void AddAssetToAlbum(UIImage image, PHAssetCollection album, string imageName)
{
try
{
PHPhotoLibrary.SharedPhotoLibrary.PerformChanges(() =>
{
// Create asset request
var creationRequest = PHAssetCreationRequest.CreationRequestForAsset();
var options = new PHAssetResourceCreationOptions
{
OriginalFilename = imageName
};
creationRequest.AddResource(PHAssetResourceType.Photo, image.AsJPEG(), options);
// Change asset request (change album by adding photo to it)
var addAssetRequest = PHAssetCollectionChangeRequest.ChangeRequest(album);
addAssetRequest.AddAssets(new PHObject[] { creationRequest.PlaceholderForCreatedAsset });
}, (success, error) =>
{
if (!success)
Console.WriteLine("Error adding asset to album");
});
}
catch (Exception ex)
{
string h = ex.Message;
}
}
See to it that you request authorization using the PHPhotoLibrary.RequestAuthorization method as we need to request access to be able to use the Photos library. Also, As of iOS 10 and above we also need to add an entry for access in the target .plist file for "Privacy - Photo Library Usage Description":
<key>NSPhotoLibraryUsageDescription</key>
<string>Access to photos is needed to provide app features</string>
Update
At the end, adding the following started showing the documents in the files app:
<key>UIFileSharingEnabled</key> <true/> <key>LSSupportsOpeningDocumentsInPlace</key> <true/>

Issue With Xamarin.Forms Images in iOS Renderer

I hope someone can help me with this weird problem.
I'm in Xamarin Forms, in a renderer. I'm passing a Xamarin.Forms.ImageSource into a ImageLoaderSourceHandler.
var_imageLoader = new ImageLoaderSourceHandler();
However, when I await the LoadImageAsync method it always returns null, rather than UIimage.
if (_view.Icon?.Source != null)
{
_iconImageView.Image =
await _imageLoader.LoadImageAsync(_view.Icon.Source);
}
My images are in the Resource directory and are BundleResourceas build action.
The file naming is correct (menu.png, menu#2x.png, menu#3x.png) and I've run out if ideas.
Anyone got a clue or two ?
Thanks
ImageLoaderSourceHandler is used if you want to download images from a Url.
Since your files are local you need to use FileImageSourceHandler
You can use this help method to get you the right type.
private static IImageSourceHandler GetHandler(ImageSource source)
{
IImageSourceHandler returnValue = null;
if (source is UriImageSource)
{
returnValue = new ImageLoaderSourceHandler();
}
else if (source is FileImageSource)
{
returnValue = new FileImageSourceHandler();
}
else if (source is StreamImageSource)
{
returnValue = new StreamImagesourceHandler();
}
return returnValue;
}

Determine whether HTTP request / response is main frame

I am using an observer on "http-on-modify-request" to analyze HTTP requests (and responses with the corresponding other observers).
Is it possible to determine whether the HTTP request / response is the main frame loading (the actual page DOM)? As opposed to another resource (image, css, sub_frame, etc.).
The docs have most of the answer you're looking for here and I've modified it below for use with the addon-sdk.
You can watch for an IFRAME by comparing the location with the top.document location.
I don't think there's an easy way to detect loading of images, etc so you'll probably want to just watch for the first hit that's not an IFRAME and regard everything else as css/image/script content loading.
var chrome = require("chrome");
var httpmods = {
observe : function(aSubject, aTopic, aData) {
console.log("observer", aSubject, aTopic, aData);
aSubject.QueryInterface(chrome.Ci.nsIHttpChannel);
var url = aSubject.URI.spec;
var dom = this.getBrowserFromChannel(aSubject);
if (dom) {
if (dom.top.document && dom.location === dom.top.document.location) {
console.log("ISN'T IFRAME");
} else {
console.log("IS IFRAME");
}
}
},
getBrowserFromChannel: function (aChannel) {
try {
var notificationCallbacks =
aChannel.notificationCallbacks ? aChannel.notificationCallbacks : aChannel.loadGroup.notificationCallbacks;
if (!notificationCallbacks)
return null;
var domWin = notificationCallbacks.getInterface(chrome.Ci.nsIDOMWindow);
return domWin;
}
catch (e) {
dump(e + "\n");
return null;
}
}
}
require("observer-service").add("http-on-modify-request", httpmods.observe, httpmods);

Resources