how to implement Exif.PCL in xamarin forms? - xamarin.forms

I am trying to create a project in which picture is taken to upload from mobile camera, but when it is taken with front camera it rotates upside down (especially Android). I have read suggestions to use Exif.PCL nuget package but dont know how to implement the same. Can anybody help me out with this ?
Thanks

Background
I had the same problem in one of my apps. After trying different approaches I've found several problems with current implementations. Generally I use XLabs, which has media picking capabilities.
Issues
First of all it lacked support for scaling and autorotating images after they are taken. That's your question. So, first of all I had to implement some after-processing as soon as the image was picked.
Second, there are problems with Android and Xamarin.Forms due do how Activities are handled in Android. The way it works on Android is you launch CameraActivity or PhotoGalleryActivity which are actually hosted in a different application. Those Activities use substential amount of system memory, and due to this operating system will try to kill non-forground processes, including your app :) Workarround for this was completely implementing photo taking flow inside of my application by creating photo taking activities from scratch. Thus, I will never leave my app, and Android runtime will never kill my application.
Solution
Taking account all of this, I've implement my own flow of Image capturing. You can find the source code HERE. The basic architecture is following:
I've created IImageService, which has methods for picking images from camera or library.
public interface IImageService
{
Task<IImage> GetImageFromLibrary();
Task<IImage> GetImageFromCamera();
}
Then I've implemented this for iOS and Android separately and used dependency injection. For iOS I use XLabs implementation, cause it works as it should there are no problems with it. For Android I've created several activities to support picking images from Camera and Library: CameraActivity, PhotoGaleryActivity, which basically replace the native image picking activities.
After I pick the image I do scaling and rotating procedure. For iOS I've created UIImageToolbox static class which has GetScaledAndRotatedImage method. For Android it's BitmapToolbox static class which has GetScaledAndRotatedBitmap method.
In my sample application I've created ImageViewModel and ImagePage to demonstrate the usage of IImageService. It should be straightforward.
How to use the sample app?
Let me give a small remark. You can use only XLabs implementation for both iOS and Android and just use BitmapToolbox and UIImageToolbox to implement the scaling and rotation. And this is answer to your question. However, if you want your app to be stable on Android you need to go a little bit dipper.
Install all the necessary nuget packages to your Forms, Droid and iOS projects. You can find the packages that are used by sample application in packages.config file of each project
I use MvvmCross Messenger plugin for broadcast messaging, if you have alternative you can easily replace it. But if you want to use it, don't forget to register dependencies in your AppDelegate and MainActivity
DependencyService.Register();
Add necessary classes to your Forms, iOS and Android projects from sample application. You can use Resharper to fix namespaces for you.
For xaml files, if you drug and drop to forms project default build action and Custom Tool are set to wrong values. Thus click the xaml file, select properties set Build Action to Embedded Resource, and Custom Tool to MSBuild:UpdateDesignTimeXaml
For android project add necessary resources from drawable, drawable-xxhdpi, layout and values folders.
In grid_cell_photo_galery_item.axml file fix namespaces. Replace ImageSample.Droid.Views.SquareRelativeLayout by your namespace.
For Android, right click Android project, select properties, go to Android Manifest and add CAMERA, READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions.
For Android, right click Android project, select properties, go to Advanced and set Max Heap Size to something like 1G, this is needed because PhotoGalaryActivity uses substantial amount of memory to display images and we need an increased heap size.
For iOS, don't forget to add dependency injection for MediaPicker in AppDelegate - DependencyService.Register<MediaPicker>();
That's all.

Related

How to use .NET 6-windows and .NET 6 targets in one library

I've segregated my WinUI 3 application into different layers: Application, Infrastructure, Presentation etc.
And all the projects have targets: net6.0-windows and I want to move it to the Uno Platform.
So, I've added a new target: net6.0
And at this moment the problem arises:
Type [WinUI] component already defines a member, called InitializeComponent or some problems with binding.
Is it possible to make such type of library with targets to net6-windows and net6.0?
For the Windows app project itself, you need to use net6-windows, as that provides additional dependencies specific to Windows app projects. All other libraries (non-app projects) can then use net6.0.
Regarding the specific error message, you are getting, the reason might be the generated files have some kind of conflict - you can try deleting the obj and bin folders and rebuild.
The easiest way to make existing Windows app support Uno would probably be to create a blank Uno solution and then migrate the code there (as the solution has already the required setup for platform-specific projects prepared and you can then just add your code.
Uno also provides templates for cross-targeted libraries, so you might be able to use similar approach. The one linked is for "UWP" solution however, so to make it WinUI, you would need to switch from uap10.0.18362 to net6-windows.

Xamarin - No resource Id shown or available in image properties

I am trying to embed an image in Xamarin and was expecting to see a resource Id appear in the properties of the image. It seems to be a problem that I cannot find an answer for. I have updated VS, JDK to 64 bit, updated Xamarin, cleaned rebuilt, restarted. I'm using the latest API (API 27 8.1)
I have checked the Xamarin forum and the VS forums and there is no answer available. In my code-behind I am writing the following:
bgImage.Source = ImageSource.FromResource("FoodSnapApps.Images.steps.jpg");
Obviously it wont work as the resource has no reference.
As always, any help will be greatly appreciated.
As stated here, in Xamarin forms local images must be loaded in the platform specific projects:
Image files can be added to each application project and referenced from Xamarin.Forms shared code. To use a single image across all apps, the same filename must be used on every platform, and it should be a valid Android resource name (ie. only lowercase letters, numerals, the underscore, and the period are allowed).
iOS - The preferred way to manage and support images since iOS 9 is to use Asset Catalog Image Sets, which should contain all of the versions of an image that are necessary to support various devices and scale factors for an application. For more information, see Adding Images to an Asset Catalog Image Set.
Android - Place images in the Resources/drawable directory with Build Action: AndroidResource. High- and low-DPI versions of an image can also be supplied (in appropriately named Resources subdirectories such as drawable-ldpi, drawable-hdpi, and drawable-xhdpi).
Windows Phone - Place images in the application's root directory with Build Action: Content.
Universal Windows Platform (UWP) - Place images in the application's root directory with Build Action: Content.
Then you can access them as follow:
In XAML: <Image Source="waterfront.jpg" />
In C#: var image = new Image { Source = "waterfront.jpg" };
I suggest you to read all that page of documentation to proper handling images in your Xamarin forms project.
HIH
I know it's an old question, but for people who may reach this page on future, code below works for me:
bgImage.Source="resource://FoodSnapApps.Images.steps.jpg"

Wrap website with cordova phonegap. What happens with audio files?

I have a learn new language site, that i want to wrap in cordova phonegap.
The app needs to work offline. I also want to make it available on the app store.
The project budget is very low. I need to find a quick way to create this app within the budget and time frame.
My question.
Is it possible to just wrap the whole site? And save it all offline.
What happens to the database? Do i need to recreate the database for the app, use sqlite ect.
Some pages will have audio files, where user can listen to the word pronunciations. What happens to the audio files. Do i need to rebuild this? Or is there a quicker way.
Can all of this be achieved by using cache?
If there is a better way of doing this please let me know.
Thanks in advance
cordova-plugin-inappbrowser provides a web browser view that displays when calling cordova.InAppBrowser.open().
var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');
The cordova.InAppBrowser.open() function is defined to be a drop-in
replacement for the window.open() function. Existing window.open()
calls can use the InAppBrowser window, by replacing window.open:
window.open = cordova.InAppBrowser.open;
The InAppBrowser window behaves like a standard web browser, and can't access Cordova APIs. For this reason, the InAppBrowser is recommended if you need to load third-party (untrusted) content, instead of loading that into the main Cordova webview. The InAppBrowser is not subject to the whitelist, nor is opening links in the system browser.

How to update Watch app with updates in core data?

We support iOS 7, so I am not using a framework. The app is mostly objective-c, and the watchkit extension mostly in swift. The AppDelegate manages the Core Data objects.
Our app allows the user to choose a configuration to change what they see. They can switch to a different configuration. When they switch, we remove most everything from NSDefaults and we remove the sqlite database and recreate it. When they switch, its basically starting over.
On the watch side, I have a swift class that has a lazy loaded Singleton of an object that manages the core data objects. But when the app resets its data, how can we report this out to the watch extension? I am guessing that I have to reset the managed object context that the extension created.
You can use MMWormHole to send messages from your iPhone app to your WatchKit extension. In your WatchKit extension you can set the stalenessInterval for your Core Data database to something really short and you will also probably want to refresh your NSManagedObjects.

MvvmCross MvxApplication class overriding for different platforms. (Plus, encryption)

I've got two questions here. The first one is just specific and another one is more general, but is a source of the first one.
So, my specific problem: I want to use Encryption (actually, Hashing) algorithms with using System.Security.Cryptography namespace (for instance, SHA256Managed class).
I found out that (happily) Xamarin has implemented those in System.dll.
But it is not portable and obviously can not be used from Core application directly.
But I've also found another great project -- PclContrib -- which allows you to do that. But, unfortunately, they don't have the implementation for Touch and Android. (However, that still works great for Desktop (Web) and Windows Phone, plus, still can be included into Core (as it uses portable project)).
Anyway, to solve that nicely, I've decided to create some base class for the encryption methods and then override core methods which require the custom dll (for any custom system).
The way I did it (at least, trying to do) was:
Defining virtual method in Core App base class:
public virtual IEncryptionProvider CreateEncryptionProvider()
Overriding Core App class in Touch project with overriding CreateEncryptionProvider (which creates an instance of TouchEncryptionProvider class instance).
Core:
public class App : MvxApplication
Touch:
public class AppTouch : App
Launching it in Touch setup.cs:
protected override Cirrious.MvvmCross.ViewModels.IMvxApplication CreateApp (
{
return new AppTouch();
}
But, that does not work for me. On startup I've got this exception message in log:
"Exception masked KeyNotFoundException: Could not find view for Mynamespace.Etc.LoginViewModel", which works fine when I do new App() instead. I am not sure if that message shows actual problem (as before it was saying the same even that was a problem with some third-party dll, unrelated to views at all). But speaking shortly, that's just a primitive inheritance of App : MvxApplication, but placed not in Core but Touch project.
So, does it requeire some more custom initialization for such situations or do I miss something else?
And, actually, more general question is how should I build such Multiplatform approaches? Actually, now I've got similar problem with HttpUtility.UrlEncode, which I would want to use in my Core project.
What is the MvvmCross "philosophy" to handle such situations?
Thank you.
For the 'viewmodel not found' problem, this is caused because mvvmcross by default only looks for viewmodels in the Assembly containing your app.
If you want it to look in other assemblies, override ViewModelAssemblies in Setup.cs - see how this done in, for example, MvvmCross - structuring shared View Models and Views
For general multplatform approach, please read questions and answers like:
Platform-specific IoC in MVVMCross
Instantiation of ViewModels and Service classes
Please also remember you don't have to use PCLs - if you prefer to use file-linking between multiple platform-specific core projects, then you can of course use this approach.
Finally, please also try to ask one question per question - I find it makes stackoverflow work better for users and with search engines too. If you need to link questions, then you can just add a hyperlink reference - stackoverflow then marks them as related.

Resources