View a specific image from the complete gallery path without browsing - xaml

I'm trying:
<Image Source="/storage/emulated/0/Pictures/Test/IMG_20200408_085036.jpg"/>
No effect.
File imageSpc = new File('/storage/emulated/0/Pictures/Test/IMG_20200408_085036.jpg');
var imageSpc = new File('/storage/emulated/0/Pictures/Test/IMG_20200408_085036.jpg');
Error, cannot create static variable for type File or var.
<Image x:Name="fotka" Aspect="AspectFit" HeightRequest = "50"
WidthRequest = "60"/>
fotka.Source = ImageSource.FromFile("/storage/emulated/0/Pictures/Test/IMG_20200408_085036.jpg");
No effect
Is possible to show specific image from gallery in XAML or at least from the code
I did enable ADB notification option in device.
In The moment image to be displayed compiler show error:
How to fix this Error?

According to your description, you want to display image using gallery path, if yes, please take a look the following code:
Firstly, you need to get image path from gallery in Android or ios.
Create interface IFileSystem in PCL(Forms)
public interface IFileSystem
{
string GetGalleryImage();
}
Then implementing this interface in platform, the example is in Android.
[assembly: Dependency(typeof(FileSystemImplementation))]
namespace demo3.Droid
{
public class FileSystemImplementation : IFileSystem
{
public string GetGalleryImage()
{
var filePath = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures);
var path = System.IO.Path.Combine(filePath.AbsolutePath, "Test/image1.jpg");
return path;
}
}
}
Add one Image control in PCL(Forms), name image1, using DependencyService to get image path.
<Button
x:Name="btn1"
Clicked="Btn1_Clicked"
Text="load image" />
<Image
x:Name="image1"
HeightRequest="100"
WidthRequest="100" />
private void Btn1_Clicked(object sender, EventArgs e)
{
var path = DependencyService.Get<IFileSystem>().GetGalleryImage();
image1.Source = ImageSource.FromFile(path);
}
This is article about DependencyService, you can take a look:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/introduction
Update:

I found, each image before show in activity must be resized to max size 4096 x 4096 px otherwise image not shown, without any errors message.

Related

Specify the color of a SVG image in .NET Maui

.NET MAUI has the ability to use SVG images which is really nice, but I haven't been able to set the color of the SVG image. The official docs state I could use the TintColor in the project file but that's not a good solution as I want to be able to use different colors depending on certain conditions. So can we somehow specify the color of a SVG image?
I just figured out that the Maui Community toolkit has a IconTintColorBehavior that does just want I want.
Usage:
<Image Source="shield.png">
<Image.Behaviors>
<toolkit:IconTintColorBehavior TintColor="Red" />
</Image.Behaviors>
</Image>
Maybe you could use skiasharp. I give some examples.
First add Nuget, such as SkiaSharp.Views.Maui.Controls, SkiaSharp.Svg.
In the xaml, define a SKCanvasView. The PaintSurface event handler is where you do all your drawing.
<StackLayout>
<skiact:SKCanvasView WidthRequest="500" HeightRequest="500" x:Name="mycanvasview" PaintSurface="mycanvasview_PaintSurface">
</skiact:SKCanvasView>
</StackLayout>
In the .cs file, implement mycanvasview_PaintSurface method. Add some code like this:
private void mycanvasview_PaintSurface(object sender, SkiaSharp.Views.Maui.SKPaintSurfaceEventArgs e)
{
SKImageInfo info = e.Info;
SKSurface surface = e.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
Stream stream = LoadStream(typeof(MainPage),"myfile.svg");
SKSvg svg = new SKSvg();
svg.Load(stream);
using (var paint = new SKPaint())
{
paint.ColorFilter = SKColorFilter.CreateBlendMode(
SKColors.Yellow,
SKBlendMode.SrcIn);
canvas.DrawPicture(svg.Picture ,paint);
}
}
private static Stream LoadStream(Type type, string v)
{
Assembly assembly = type.GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream(v);
return stream;
}
You svg file will change the color.
I hope my answer could help you.

custom entry box with icon for xamarin form (android,ios)

Entry box should be rounded with an icon to the left or right in it. I'm using the code presented here to create this custom entry.
1. Remove the rectangular border of Entry
Used CustomRender to achieve this.
Forms
public class NoUnderlineEntry : Entry
{
public NoUnderlineEntry()
{
}
}
Android
Set Background to null
public class NoUnderLineEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
this.Control.Background = null;
}
}
iOS
Set BorderStyle to None
public class NoUnderlineEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
this.Control.BorderStyle = UIKit.UITextBorderStyle.None;
}
}
2. Placing Image next to Entry
Adding Image and Entry to the same Grid in two columns.
3. Adding Rounded border to the Entry and Image
Add them inside a Frame with CornerRadius.
XAML
<StackLayout>
<Frame
Padding="10, 5, 10, 5"
HasShadow="False"
BorderColor="Gray"
CornerRadius="30">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<local:NoUnderlineEntry/>
<Image Source="icon.png" Grid.Column="1" WidthRequest="50" Aspect="AspectFit"/>
</Grid>
</Frame>
</StackLayout>
UI result:
Please note: I won't present a copy-and-paste-able answer, but rather an outline on how to add the images. You'll have to integrate the code in your solution by yourself.
On iOS
There already is an answered question on how to achieve this with Swift on iOS, you can find it here.
Basically what to do is to set the right view (or left view respectively) on the UITextField from your custom renderer (in OnElementChanged).
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
var imageView = new UIImageView(new CGRect(0, 0, 20, 20));
var image = UIImage.FromFile("ic_location.png");
imageView.Image = image;
this.Control.RightView = imageView;
this.Control.RightViewMode = UITextFieldViewMode.Always;
}
This sets the view in the right of the UITextField to a UIImageView. If you wanted to show the icon before the text instead, you'd have to set LeftView and LeftViewMode instead. This is how it looks like. (I intentionally did not inline the image, because it rendered the answer less redable.)
Of course the file ic_location.png has to be in your platform projects resources.
You may need some fine tuning, but basically that's it.
On Android
The TextView.setCompoundDrawablesWithIntrinsicBounds
Sets the Drawables (if any) to appear to the left of, above, to the right of, and below the text. Use null if you do not want a Drawable there. The Drawables' bounds will be set to their intrinsic bounds. (source)
By loading the icon from the resource and setting it with SetCompoundDrawablesWithIntrinsicBounds (uppercase now, since we're now on C#) you can display the Entry with the icon:
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
this.Control.SetCompoundDrawablesWithIntrinsicBounds(null, null, this.GetIcon(), null);
this.Control.CompoundDrawablePadding = 25;
}
private Drawable GetIcon()
{
int resID = Resources.GetIdentifier("ic_location", "drawable", this.Context.PackageName);
var drawable = ContextCompat.GetDrawable(this.Context, resID);
var bitmap = ((BitmapDrawable)drawable).Bitmap;
return new BitmapDrawable(Resources, Bitmap.CreateScaledBitmap(bitmap, 20, 20, true));
}
This is how the Android version looks like.
For showing the icon on left left, pass the drawable to the first parameter instead of the third.

Xamarin.Forms add ScrollView to ContentPage and wrap existing content

I have a Xamarin.Forms page written in .xaml On iOS platform only I am trying to wrap the content of the page in ScrollView to help fix resizing issue when keyboard is shown.
The page looks something like this:
<base:mypagebase...>
<ContentPage.Resources>
...
</ContentPage.Resources>
<ContentPage.Content>
<RelativeLayout x:Name="ViewContentLayout" VerticalOptions="FillAndExpand">
....
</RelativeLayou>
</ContentPage.Content>
</base:mypagebase>
I am trying in the constructor of my mpage.xaml.cs after InitializeComponent() to wrap my RelativeLayout in ScrollView
Something like this:
if (Device.RuntimePlatform == Device.iOS)
{
var scroll = new ScrollView();
scroll.Orientation = ScrollOrientation.Vertical;
scroll.VerticalOptions = LayoutOptions.FillAndExpand;
scroll.Content = ViewContentLayout;
Content = scroll;
}
It passes through but throws exception later:
Object reference not set to an instance of an object
at Xamarin.Forms.RelativeLayout.OnSizeRequest (System.Double widthConstraint, System.Double heightConstraint) [0x00017] in RelativeLayout.cs:185
The order in which the properties are called matters, seems like the Content root had to be set first:
if (Device.RuntimePlatform == Device.iOS)
{
var viewContentLayout = ViewContentLayout;
var scroll = new ScrollView();
Content = scroll;
scroll.Content = viewContentLayout;
}

multiple image at the same component (image placeholder)

In my app, I load an image from URL.
<Image Source="{Binding Image}" />
I want to load a small image from local in advance. After the image from remote is downloaded completely, replace or overwrite this local image.
Is there any simple way to achieve this function?
Such as multiple background image in a div.
http://css-tricks.com/stacking-order-of-multiple-backgrounds/
This is the simplest way to achieve what you desire;
<Grid>
<Image Source="YourLocalImage" />
<Image Source="{Binding Image}" />
</Grid>
So, in your app until your URL image is loaded, your local image will be visible & once your URL image is loaded, that will be visible. See, if this helps.
Not a built-in functionality in xaml...but this would do the trick.
At first you put the local image location as a value in image property. Then you need to have a Image downloaded completed event so that you can detect when Image is successfully downloaded from remote location.
Inside this event you can replace Image property value so that it changes the image in the UI. But make sure your class in which Image is defined has implemented INotifyPropertyChanged interface.
public class MyData : INotifyPropertyChanged{
private string image;
public string Image {
set{
Notify("Image");
image = value;
}
get{ return image; }
}
public event PropertyChangedEventHandler PropertyChanged;
private void Notify(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

The given System.Uri cannot be converted into a Windows.Foundation.Uri

I'm trying to programmatically load a BitmapImage in a XAML Metro app. Here's my code:
var uri = new Uri("/Images/800x600/BackgroundTile.bmp", UriKind.RelativeOrAbsolute);
var imageSource = new BitmapImage(uri);
The second line crashes with a System.ArgumentException:
The given System.Uri cannot be converted into a Windows.Foundation.Uri. Please see http://go.microsoft.com/fwlink/?LinkID=215849 for details.
The link just goes to the MSDN home page, so it's no use.
I've also tried removing the leading /, in case WinRT has different expectations about relative URIs, but I still get the same exception.
Why am I getting this exception for what seems to be a perfectly valid URI?
In the Consumer Preview, the correct URL format has apparently changed to ms-appx:/Images/800x600/BackgroundTile.bmp
Judging from the documentation for Windows.Foundation.Uri, it looks like WinRT doesn't support relative URIs. I tried a pack:// URI, but that gave me a UriFormatException, so apparently that's not the way to do it in WinRT either.
I found the answer on this thread: MS invented yet another URI format for WinRT resources. This works:
new Uri("ms-resource://MyAssembly/Images/800x600/BackgroundTile.bmp")
Note that you don't add your actual assembly name -- the MyAssembly part is literal text.
You will need to use the page's BaseUri property or the image control's BaseUri property like this:
//using the page's BaseUri property
BitmapImage bitmapImage = new BitmapImage(this.BaseUri,"/Images/800x600/BackgroundTile.bmp");
image.Source = bitmapImage;
or
//using the image control's BaseUri property
image.Source = new BitmapImage(image.BaseUri,"/Images/800x600/BackgroundTile.bmp");
you can see the reason and solution here
In case you're still having issues or are being asked to find an app to open the link, are you trying to use a WebView? If so, try using ms-appx-web instead of ms-appx.
An example:
this.webBrowser.Navigate(new Uri("ms-appx-web:///level/level/level/index.html"));
Also note the lack of the URIKind parameter--evidently not needed at all in these instances.
(I believe you may need to vary the leading forward slashes depending on your reference)
This would work in XAML but would not work in code... so each control or page has a BaseUri property which you can use to build the proper uri for assets... here is an example:
imageIcon.Source = new BitmapImage(new Uri(this.BaseUri, "Assets/file.gif"));
// Or use the base uri from the imageIcon, same thing
imageIcon.Source = new BitmapImage(new Uri(imageIcon.BaseUri, "Assets/file.gif"));
also you would need to set the build action to "Content" rather than Embedded Resource... otherwise you need to use the ms-resource:// protocol.
I know this is old but I hope this helps. I wrote this in XAML and it worked for me. The Ide I'm using is vs-2015 with win-10.
<Window>
<Grid>
<Grid.Background>
<ImageBrush ImageSource="NameOfYourImage.JPG or any Image type"/>
</Grid.Background>
<GroupBox x:Name="groupBox" Header="GroupBox" HorizontalAlignment="Left" Height="248" Margin="58,33,0,0" VerticalAlignment="Top" Width="411">
<GroupBox.Background>
<ImageBrush ImageSource="NameOfYourImage.JPG or any Image type"/>
</GroupBox.Background>
</GroupBox>
</Grid>
</Window>
MVVM ;)
public static ImageSource SetImageSource(string uriPath)//.com/image or some path
{
// this method very good for mvvm ;)
try
{
//In Model - public ImageSource AccountPhoto { get; set; }
//AccountPhoto = SetImageSource("some path");
return return new BitmapImage()
{
CreateOptions = BitmapCreateOptions.IgnoreImageCache,
UriSource = new Uri(uriPath)
};
}
catch
{
Debug.WriteLine("Bad uri, set default image.");
return return new BitmapImage()
{
CreateOptions = BitmapCreateOptions.IgnoreImageCache,
UriSource = new Uri("ms-appx:///Avatar/Account Icon.png")
};
}
}