Closed marcelwgn closed 1 year ago
Hello guys, I'm thinking in implementing the method GetImagePropertiesAsync that was suggestion on workaround. https://docs.microsoft.com/en-us/uwp/api/windows.storage.fileproperties.imageproperties?view=winrt-19041 Would this be the best way?
Provides access to the image-related properties of an item (like a file or folder).
You will not be able to use this API to get image properties, as images may come from network sources, local files, local streams, or from computed images.
Each platform has its own ways to get image sizes, depending on what's done in all ImageSource.*.cs
implementations in https://github.com/unoplatform/uno/blob/2a76c3be2e5ff5325e37e50f4fb54b7724359906/src/Uno.UI/UI/Xaml/Media.
GitHubBuild Mobile, Desktop and WebAssembly apps with C# and XAML. Today. Open source and professionally supported. - uno/src/Uno.UI/UI/Xaml/Media at 2a76c3be2e5ff5325e37e50f4fb54b7724359906 · unoplatfor...
Hey @CesarRabelo,
Taking into account what @jeromelaban mentioned, I think you could take the following approach:
It affects wasm as well. No workaround means it is a show-stopper for now.
I'm about to implement a workaround by creating an HtmlImage
and set the src
manually. However, the class is not found, and when I write new UIElement("img")
, the compiler complains there is no such constructor. Checking the source, everything is public so they should be accessible. Am I missing anything? Thanks!
HtmlImage
is not meant to be used directly and is hidden from the public APIs accessible from the apps, but you can create your own control based on img
if you need to.
Why do you need the size of the image, out of curiosity? On WebAssembly, since Uno is giving Urls directly to the control, we don't really have a way to get the image size in the same way UWP does. The Image
control gets the size once the image has been loaded, but can't get it before that.
I need it to compute scale informations to control zoom and scaling. I cant use scroller viewer becoz scrollerviewer's scale in wasm isnt working 😅.
In js, we can instantiate Image
and set src to force it to load and grab size there, and I think we can do similar things with HtmlImage
. Long term, bitmap source should use similar implementation (better yet, implement BitmapEncoder
and use it in bitmap source), so others can get the size easily. I dont mind submiting PRs to fix, but being unable to workaround this for now is a show stopper.
I might try calling js using wasm runtime js interop but it is really not ideal. Being able to use wasm specific class like HtmlImage
directly is better. What is the reasoning behind hiding implementation specific class? Users would need to guard such code use with #if
anyways.
For those who are affected by this issue and is on wasm, you can use this workaround to get image size:
#if __WASM__
var result = await WebAssemblyRuntime.InvokeAsync("(async () => {"
+ "var promise = new Promise((resolve) => {"
+ "var i = new Image();"
+ "i.onload = function() { resolve(\"\" + i.width + \",\" + i.height); };"
+ $"i.src = \"{_imageSource.Uri}\";"
+ "});"
+ "return await promise;"
+ "})()");
var sizes = result.Split(",");
if (sizes.Length != 2)
{
throw new InvalidOperationException($"Failed to get image size via js interop. Result: {result}");
}
const int widthIndex = 0;
const int heightIndex = 1;
Width = uint.Parse(sizes[widthIndex]);
Height = uint.Parse(sizes[heightIndex]);
I think BitmapSource
etc should get the image size accordingly before ImageOpened
is called. Should I submit a PR? @jeromelaban
Possible fixes:
BitmapSource
by getting image size using method above.BitmapEncoder
, at least getting image size, using method above. Then, fix all BitmapSource
by using BitmapEncoder
to get size.Engineering wise I think (2) is a better solution, but I reckon it might not be feasible due to API surface concerns, etc. Please lemme know which works for Uno so I can proceed to work on either one of these (I'd like to omit this workaround in my codebase). If I should open a new issue for the implementation, please lemme know. Thanks!
@roxk There is a bigger refactoring in progress for ImageSource
and related classes inside the SVG PR I have open so I suggest waiting for it to be merged before submitting this change, but it definitely would be great if you were able to contribute it afterwards 🚀 !
This is done and merged in 4x
Current behavior
Using the following code, you can capture and "create" a Bitmap image to use as source for an image for example:
However
source.PixelHeight
,source.PixelWidth
,source.DecodePixelHeight
andsource.DecodePixelWidth
are 0.Expected behavior
These properties should be not 0 and usable, e.g. to use them to size correctly or convert a bytestream into a different image object.
How to reproduce it (as minimally and precisely as possible)
See code example above.
Workaround
No workarounds found so far. A possible workaround would have been to use GetImagePropertiesAsync to get the necessary information, unfortunately this isn't implemented yet.
Environment
Nuget Package:
Nuget Package Version(s): Uno.UI: 3.5.0 Uno.Core: 2.1.0 Affected platform(s):
IDE:
Relevant plugins:
Anything else we need to know?
Found while trying to create a RGBLuminanceSource to use for QR code scanning.