I have a (hopefully) simple question (I don’t have found an answer, that fit’s by all of my searches).
I work with Xamarin.Forms 1.4.1-Pre-1. In my app, I have:
byte[] AvatarErfassung; // Bytearray, to later update the webservice
var Avatar = new Image { HeightRequest = 71, WidthRequest = 61, HorizontalOptions = LayoutOptions.Start };
Avatar.Source = "SymbolMann.jpg";
where the image "SymbolMann.jpg” is included as project-resource (in each project) and showed on a page (without problems).
I now want to put the image in a byte-array to send it to our webservice. I don't have found any way to access the image "SymbolMann.jpg" (to load it in a byte-array) or to use (however) the Avatar.Source therefore.
Question:
How to get the image “SymbolMann.jpg” into the byte-array “AvatarErfassung” ?
Thanks for every answer
Hi Dimitris
Thanks for your (fast) replay.
As I wrote, I work with Xamarin.Forms.
The images are stored as resources: in \Resources\Drawable\ (for Android), \Resources\ (for iOS) and in the root (for WP). I have to load the image on a content-page.
If I overtake your code, to the line:
var assembly = this.GetType().GetTypeInfo().Assembly;
I have the error-message (translated to English):
“System.Type don’t contain a definition for GetTypeInfo method (is a using missing?)”
Do I have to add a specific using?
You write: // you can replace "this.GetType()" with "typeof(MyType)", where MyType is any type in your assembly.
What do I have to place as type?
= typeof(????).GetTypeInfo().Assembly:
Thanks for a further reply.
Update #2:
Firts, thanks for your patience…
Unfortunately in VS2013, I don’t find any function “resolve” that shows me the missing using - but I have find out the missing using my self :-)
In the meantime I have added using System.Reflection;
Now, the line: var assembly = this.GetType().GetTypeInfo().Assembly;
is resolved and compiled without error
Further, I have changed the type of the .jpg from “Android Resource” to “Embedded Ressource”.
The App then crashes in the line: long length = s.Length; as it seems that s is null (I think the jpg is not found)
Further - if I change the type to “Embedded Ressource” - the image is not found any more by Xamarin.Forms (Avatar.Source = "SymbolMann.jpg";)
If I change the type of the .jpg to “Compile” I can’t compile the app.
Error-message: A namespace can’t contain directly members like fields or methods.
So… what is the correct type to the resource (so that it can be loaded with assembly.GetManifestResourceStream()?
Do I have to add something to the filename (SymbolMann.jpg) so that it will be found?
How do I have to change Avatar.Source = "SymbolMann.jpg" so that it is found (if I change the type from “Android Resource” to anything else)?
Once again my needs:
On a registration-page, default-images (symbols) are showed as avatar for man and woman in a standard-Xamarin.Forms image (avatar.source = “SymbolMann.jpg” / “SymbolFrau.jpg”).
The .jpg’s are stored in the standard-directories for each project (Android, iOS and WP) where the are accessible without problems from the image-object.
The user then can take one of the default-images or load another one over mediapicker.
If the user the tap the button “Register”, I have to create a byte-array from the Image to send it via json to our webservice.
If the user select another image via mediapicker, I have access to the stream, the problem is, to become a byte-array from the default-images (in every platform).
Once again thanks for your help...
6条答案
按热度按时间0ve6wy6x1#
You can easily do this, by reading the resource stream from the assembly:
To get the assembly that holds the embedded resources of your project you need to call the
GetTypeInfo
method on a type included in that assembly. Hence,typeof(X)
, where "X" is any type in your assembly. For example, if you are using a custom page calledMyCustomPage
:... this is what you would pass:
typeof(MyCustomPage)
You need any instance of type
Type
(this is what thetypeof
keyword returns basically). The alternative is to call theGetType()
method on any object that is included in your project.Note that you will not be able to get the correct assembly if you call
typeof(X)
on a type that is not included in your project. Eg. callingtypeof(ContentPage).GetTypeInfo().Assembly
, would return the assembly that theContentPage
type resides in. Which is not the one that includes your resources. I hope this is not confusing. If it is, please let me know.Now, the
GetTypeInfo
method is an extension method included in theSystem.Reflection
namespace. When the text editor in Xamarin Studio does not recognize something, it highlights it with red. Right-clicking on that will give you a Resolve option in the context menu:If the type or method can be resolved, it will show that option.
More on images in Xamarin Forms here .
nszi6y052#
Thanks @FredWenger and @Dimitris - here's my solution based on both your answers:
MyProject\DaffyDuck.jpg
Embedded Resource
(file properties -> build action)ImageDataFromResource("MyProject.DaffyDuck.jpg")
Notice that you need to include the project name to get the assembly name *.
ImageView.Source = ImageSource.FromStream(() => new MemoryStream(imageData));
var names = assembly.GetManifestResourceNames();
and see what is listed in your project.rm5edbpk3#
我使用VS2013-update 2,Xamarin.Forms(1.4.1-Pre1),我的应用程序基于模板**"空白应用程序(Xamarin.Forms共享)"(非PCL),我使用所有平台(Android,iOS,WP)。
在用户注册页面上,用户可以选择一个图像作为头像(随后显示在他的帖子中)。根据用户的性别,显示了两个默认图像(一个用于男性,一个用于女性)。然后,用户可以超越其中一个默认图像或从媒体选择器中选择另一个图像。
默认图像存储在内容图像的默认位置(对于Android,例如,在/Resources/Drawable/**下)。
图像显示在XF标准图像对象中,图像源="xxx.jpg"。
这已经没有问题了。
由于用户数据(包括头像)存储在SQL服务器上(通过Json-Web服务),我必须将图像数据转换为字节数组(然后将其与其他数据一起作为字符串发送到Web服务)。
问题是,从默认目录加载图像并将其转换为字节数组(由此文件访问是问题-〉无法访问)。
感谢Dimitris,引导我在正确的方向,我已经实现了以下解决方案:
在所有项目(Android、iOS和WP)中,我都添加了一个新目录"\Embedded"(直接在根目录下)。然后,我在此目录中复制了我的两个jpg("SymbolMann.jpg"和"SymbolFrau.jpg")(适用于所有平台)。
然后,我将资源类型更改为映像,例如从"AndroidResource"更改为**"Embedded Resource"**(对于所有平台,类型相同)。
在应用程序的启动代码(app.cs)中,我添加了:
其中GV.cEmbeddedAblage只是一个全局变量。
为了 checkout 命名空间名称,我必须右键单击每个平台的项目,然后查看已确定的命名空间名称(在您的项目中可能会有所不同)。
.Embedded.是新创建的目录(在所有平台上都具有相同的名称)。
此外,我还为男性图像(GV.ByteSymbolMann)和女性图像(GV.ByteSymbolFrau)创建了全局字节数组。
在注册页面的启动代码中,我添加了:
将. jpg加载到image-object中的代码,我不得不从以下代码进行更改:
至
然后,我在另一个字节数组中接管选定的字节数组(与显示图像并行)(以便稍后作为字符串上传到Web服务)
如果用户更改选择(例如,更改为女性):
注意:如果用户从MediaPicker选择另一个图像,我可以直接访问流,所以这从来不是问题所在。
"最后感谢迪米特里斯"
guykilcj4#
Adding on to noelicus's answer :
Setup
MyProject\pizza.png
Build Action
->EmbeddedResource
Code
Example
velaa5lx5#
我遇到了很多问题。我的项目已经在其他地方使用FFimageLoading了,我发现这是将.png作为流加载的最简单的方法:
请确保您的资源文件在iOS和Droid项目中具有相同的名称。它们可能已经将其构建操作设置为“BundleResource”(iOS)或“AndroidResource”(Droid)。
当然,你必须安装FFimageLoading Nuget,但你会很高兴你这样做了。
7kjnsjlb6#
我使用noelicus给出的方法打印ManifestResourceNames数组中的所有名称,我发现我的图像名称是
ProjectName.Droid.image_name.jpeg
。然后我把方法调用从assembly.GetManifestResourceStream("image_name.jpg")
改为assembly.GetManifestResourceStream("ProjectName.Droid.image_name.jpeg")
。它工作了。所以正确的答案是:1.将图像存储在PCL的根文件夹中。
1.使其生成操作在属性中作为嵌入资源
1.然后打印
<b><i>var names = assembly.GetManifestResourceNames()</i></b>
数组,它将是一个字符串数组,可以使用1.在那里,您将看到image的资源名称,然后使用方法