How can I set background color when take transparency image from gallery - xamarin

I want to set the background color of an image when take an image from the gallery because if i take transparency image it set automatically black background behind image.
But if i keep transparency image in Resources-->drawable folder then it show
given red background
<Grid Grid.Column="1" BackgroundColor=">
<Image x:Name="RestaurantImage" Source="trans.png" BackgroundColor="Red"/>
</Grid
This is my take image code :
private async void ImageTapped(object sender, EventArgs e)
{
string action = await UserDialogs.Instance.ActionSheetAsync("PickPhoto", "Cancel", null, null, "Take Photo", "Pick From Gallery");
MediaFile file = null;
if (action == "Take Photo")
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
UserDialogs.Instance.Alert("No Camera", ":( No camera avaialble.", "OK");
return;
}
file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,
Directory = "Sample",
Name = "test.png"
});
}
else if (action == "Pick From Gallery")
{
if (!CrossMedia.Current.IsPickPhotoSupported)
{
UserDialogs.Instance.Alert("PhotosNotSupported", "PermissionNotGrantedToPhotos.", "OK");
return;
}
else
{
file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions
{
PhotoSize = PhotoSize.Medium
});
}
}
else
{
return;
}
if (file == null)
return;
Stream s = file.GetStream();
RestaurantImage.Source = ImageSource.FromStream(() =>
{
file.Dispose();
return s;
});
}

You can see if the effect is what you want
1.create a CustomImage.cs :
public class CustomImage:Image
{
}
2.create a CustomImageRenderer in Droid project:
[assembly: ExportRenderer(typeof(CustomImage), typeof(CustomImageRenderer))]
namespace App18.Droid
{
class CustomImageRenderer:ImageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
if (Control != null)
{
ImageView image = Control as ImageView;
image.SetColorFilter(Android.Graphics.Color.Red, Android.Graphics.PorterDuff.Mode.DstOver);
}
}
}
}
finally use CustomImage load image

#saamer and #leo thanks for help me :)
I resolved my issue "set background color when take transparency image from gallery", when i used PhotoSize = PhotoSize.Medium then it's set black background behind transparent image but if i used PhotoSize = PhotoSize.Full it's set transparency background behind transparent image.
this is my get image from gallery code :
private async void ImageTapped(object sender, EventArgs e)
{
string action = await UserDialogs.Instance.ActionSheetAsync("PickPhoto", "Cancel", null, null, "Take Photo", "Pick From Gallery");
MediaFile file = null;
if (action == "Take Photo")
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
UserDialogs.Instance.Alert("No Camera", ":( No camera avaialble.", "OK");
return;
}
file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,
Directory = "Sample",
Name = "test.png"
});
}
else if (action == "Pick From Gallery")
{
if (!CrossMedia.Current.IsPickPhotoSupported)
{
UserDialogs.Instance.Alert("PhotosNotSupported", "PermissionNotGrantedToPhotos.", "OK");
return;
}
else
{
file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions
{
PhotoSize = PhotoSize.Full
});
}
}
else
{
return;
}
if (file == null)
return;
Stream s = file.GetStream();
s.Position = 0;
RestaurantImage.Source = ImageSource.FromStream(() =>
{
file.Dispose();
return s;
});
}

Related

while deny the camera permission in android it wont ask again

first time application asking permission for the camera, if we deny the permission it won't ask again if we allow its working fine ??
var scanPage = new ZXingScannerPage();
var cameraStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
if (cameraStatus != PermissionStatus.Granted)
{
var results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Camera });
cameraStatus = results[Permission.Camera];
if (cameraStatus == PermissionStatus.Granted)
{
// Navigate to our scanner page
await Navigation.PushAsync(scanPage);
scanPage.OnScanResult += (result) =>
{
Device.BeginInvokeOnMainThread(async () =>
{
await Navigation.PopAsync();
txtbarcode.Text = result.Text;
});
};
}
else if (cameraStatus == PermissionStatus.Unknown)
{
await Navigation.PushAsync(scanPage);
scanPage.OnScanResult += (result) =>
{
Device.BeginInvokeOnMainThread(async () =>
{
await Navigation.PopAsync();
txtbarcode.Text = result.Text;
});
};
}
If we deny the camera permission, again its asks while opening camera until we allow the permission.
I wrote a demo about this.
https://github.com/851265601/CheckPermissionDemo
This a GIF of this demo.
Did you check the permission every time when you use the camera function? In this demo, when i click the button ,it will check the permission, then give the result to users, if not give the permission, it will still ask the persmission like the following code.
async void ButtonPermission_OnClicked(object sender, EventArgs e)
{
if (busy)
return;
busy = true;
((Button)sender).IsEnabled = false;
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
await DisplayAlert("Pre - Results", status.ToString(), "OK");
if (status != PermissionStatus.Granted)
{
status = await Utils.CheckPermissions(Permission.Camera);
await DisplayAlert("Results", status.ToString(), "OK");
}
busy = false;
((Button)sender).IsEnabled = true;
}
}
When DisplayAlert was appear, it are used MainApplication for different life cycle
namespace CheckPermissionDemo.Droid
{
//You can specify additional application information in this attribute
[Application]
public class MainApplication : Application, Application.IActivityLifecycleCallbacks
{
public MainApplication(IntPtr handle, JniHandleOwnership transer)
: base(handle, transer)
{
}
public override void OnCreate()
{
base.OnCreate();
RegisterActivityLifecycleCallbacks(this);
//A great place to initialize Xamarin.Insights and Dependency Services!
}
public override void OnTerminate()
{
base.OnTerminate();
UnregisterActivityLifecycleCallbacks(this);
}
public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
{
CrossCurrentActivity.Current.Activity = activity;
}
public void OnActivityDestroyed(Activity activity)
{
}
public void OnActivityPaused(Activity activity)
{
}
public void OnActivityResumed(Activity activity)
{
CrossCurrentActivity.Current.Activity = activity;
}
public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
{
}
public void OnActivityStarted(Activity activity)
{
CrossCurrentActivity.Current.Activity = activity;
}
public void OnActivityStopped(Activity activity)
{
}
}
}

Flash Light and other buttons not visible in ZXing.Mobile.MobileBarcodeScanner

I am using below code to scan bar codes. I have set the cancel and flash buttons texts but its not visible on the UI. Its working fine in iOS but not in Android.
See below code
public async Task StartScan()
{
var scanPage = new ZXing.Mobile.MobileBarcodeScanner();
this.cancelTimer = new CancellationTokenSource();
scanPage.AutoFocus();
scanPage.TopText = "Place the barcode between the red line";
scanPage.CameraUnsupportedMessage = "Camera doesnt supports AUTOFOCUS.";
scanPage.BottomText = "If it doesnt autofocus, touch the screen to autofocus";
scanPage.CancelButtonText = "<< Back";
scanPage.FlashButtonText = "Turn Flash";
scanPage.UseCustomOverlay = false;
Device.StartTimer(new TimeSpan(0, 0, 0, 3, 0), () =>
{
scanPage.AutoFocus();
// scanPage.BottomText = "focusing";
return true;
});
ZXing.Result result = null;
CancellationTokenSource cts = this.cancelTimer;
TimeSpan ts = new TimeSpan(0, 0, 0, 2, 0);
Device.StartTimer(ts, () =>
{
if (cts.IsCancellationRequested)
{
return false;
}
if (result == null)
{
scanPage.AutoFocus();
return true;
}
return false;
});
result = await scanPage.Scan(new MobileBarcodeScanningOptions
{
TryHarder = false,
AutoRotate = false,
UseNativeScanning = true,
PossibleFormats = GetAvailableFormats(),
});
if (result != null && !string.IsNullOrWhiteSpace(result.Text))
{
await Stop();
await ProcessResult(result.Text);
}
await Stop();
}
So from the above code, Bottom and Top texts are appearing but not the buttons for which code is like below.
scanPage.CancelButtonText = "<< Back";
scanPage.FlashButtonText = "Turn Flash";
Can anyone help me to get this?

ZXing is not scanning on Android (Xamarin app)

I am using below code to scan a QR code in my Xamarin. I am currently testing it on Samsung Galaxy (Android) and I am able to view the camera streaming but it is not scanning any QR code.
How can I fix this please to get the result of the QR scanned?
public void Scan()
{
try
{
scanner.Options = new MobileBarcodeScanningOptions()
{
UseFrontCameraIfAvailable = false, //update later to come from settings
PossibleFormats = new List(),
TryHarder = true,
AutoRotate = false,
TryInverted = true,
DelayBetweenContinuousScans = 2000,
};
scanner.VerticalOptions = LayoutOptions.FillAndExpand;
scanner.HorizontalOptions = LayoutOptions.FillAndExpand;
// scanner.IsVisible = false;
scanner.Options.PossibleFormats.Add(BarcodeFormat.QR_CODE);
// scanner.Options.PossibleFormats.Add(BarcodeFormat.DATA_MATRIX);
// scanner.Options.PossibleFormats.Add(BarcodeFormat.EAN_13);
scanner.OnScanResult += (result) => {
// Stop scanning
scanner.IsAnalyzing = false;
scanner.IsScanning = false;
if (scanner.IsScanning)
{
scanner.AutoFocus();
}
// Pop the page and show the result
Device.BeginInvokeOnMainThread(async () => {
if (result != null)
{
await DisplayAlert("Scan Value", result.Text, "OK");
}
});
};
mainGrid.Children.Add(scanner, 0, 1);
}
catch (Exception ex)
{
DisplayAlert("Scan Value", ex.ToString(), "Error");
}
}
Maybe you are using the wrong event handler, or missing an event, also the camera never focuses:
the condition is never true, due to this fragment of code:
scanner.IsScanning = false;
if (scanner.IsScanning)
{
scanner.AutoFocus();
}

Xamarin Forms Grid - change cell view via button

I have a page in which I display two different charts, depending on a button click. At the moment I change charts this way:
protected void ClickedChangeChart()
{
if (chartType == true)
{
chartType = false;
Navigation.PushAsync (new MainPage (false));
}
else
{
chartType = true;
Navigation.PushAsync (new MainPage (true));
}
}
chartType is a bool and depending on it's value I choose which chart to load using this statement in OnAppearing():
protected override async void OnAppearing ()
{
// some code
ChartView chartView = new ChartView
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
HeightRequest = 300,
WidthRequest = 400
};
if (chartType == true)//true = candle
{
candleModel = new CandleModel ();
chartView.Model = await candleModel.GetModel ();
}
else if(chartType == false) //false = line
{
lineModel = new LineModel ();
chartView.Model = await lineModel.GetModel ();
}
//here I create a grid, add some children to it and the add the chartView
grid.Children.Add (chartView, 1, 6, 1, 3);
Content = grid;
}
The problem is that when I want to switch the charts I have to reload the whole page, which isn't what I want. How can I make it so when I click a button I calls a function which switches the model for the chart? I suppose it will be something like this, but I can't get it to work:
public async void ClickedButton()
{
grid.Children.Remove(chartView);
if (chartType == true)
{
candleModel = new CandleModel ();
chartView.Model = await candleModel.GetModel ();
}
else if(chartType == false)
{
lineModel = new LineModel ();
chartView.Model = await lineModel.GetModel ();
}
grid.Children.Add(chartView);
}
UPDATE:
Using Daniel Luberda's solution, I managed to get it to work with this:
btnChartType.Clicked += async delegate {
Device.BeginInvokeOnMainThread (async () => {
grid.Children.Remove (chartView);
if (isCandle == true) {
candleModel = new CandleModel ();
chartView.Model = await candleModel.GetModel ();
isCandle = false;
} else if (isCandle == false) {
lineModel = new LineModel ();
chartView.Model = await lineModel.GetModel ();
isCandle = true;
}
grid.Children.Add (chartView, 1, 6, 1, 3);
});
};
You can't get it to work because you have an async method which means that you're doing it on another thread. You can change UI only from UI thread. Also async void will swallow all exceptions, it's better to use async Task instead.
// THAT WILL WORK
public async void ClickedButton() // but public async Task would be better
{
Device.BeginInvokeOnMainThread(async () => {
grid.Children.Remove(chartView);
if (chartType == true)
{
candleModel = new CandleModel ();
chartView.Model = await candleModel.GetModel ();
}
else if(chartType == false)
{
lineModel = new LineModel ();
chartView.Model = await lineModel.GetModel ();
}
grid.Children.Add(chartView);
});
}

Set Image Source on return from Gallery/Camera?

I have an Image view I'm having trouble setting the source for. I'm using a button to execute a TakePictureCommand which calls the TakePicture() method (shown below) which in turn sets my source "ImageSource". Debugging the method shows the image is coming in, but I never see it come up in the UI.
I may not be setting the binding for the Image properly, this is what I have:
Image avatar = new Image();
avatar.Source = ImageSource;
Button setImageBtn = new Button{ Text = "Photo" };
setImageBtn.Clicked += async (sender, e) =>
{
string action = await DisplayActionSheet(
"Event Photo", "Cancel", null, OPTION_CAMERA, OPTION_GALLERY);
if(action == OPTION_CAMERA) {
TakePictureCommand.Execute(null);
}
else if(action == OPTION_GALLERY) {
SelectPictureCommand.Execute(null);
}
};
TakePicture()
private async Task<MediaFile> TakePicture()
{
Setup();
ImageSource = null;
return await _mediaPicker.TakePhotoAsync(
new CameraMediaStorageOptions {
DefaultCamera = CameraDevice.Front,
MaxPixelDimension = 400
}).ContinueWith(t =>
{
if (t.IsFaulted)
{
Status = t.Exception.InnerException.ToString();
}
else if (t.IsCanceled)
{
Status = "Canceled";
}
else
{
var mediaFile = t.Result;
ImageSource = ImageSource.FromStream(() => mediaFile.Source);
return mediaFile;
}
return null;
}, _scheduler);
}
What am I missing here?
Below approach is working for me:
First, in XAML I added Image view
<Image Source="{Binding ImageSource}" VerticalOptions="Fill" HorizontalOptions="Fill"
Aspect="AspectFit"/>
Second, in ViewModel I added ImageSource property like this:
public ImageSource ImageSource
{
get { return _imageSource; }
set { this.SetProperty(ref _imageSource, value); }
}
Third, in command handler:
await TakePicture ();
Forth, code of TakePicture() method the same as you wrote.
My Setup():
if (_mediaPicker != null)
return;
var device = Resolver.Resolve<IDevice>();
_mediaPicker = DependencyService.Get<IMediaPicker>() ?? device.MediaPicker;

Resources