Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
302 views
in Technique[技术] by (71.8m points)

c# - Xamarin.Forms: How to load an image from Resources into a byte-array?

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 ResourcesDrawable (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...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can easily do this, by reading the resource stream from the assembly:

var assembly = this.GetType().GetTypeInfo().Assembly; // you can replace "this.GetType()" with "typeof(MyType)", where MyType is any type in your assembly.
byte[] buffer;
using (Stream s = assembly.GetManifestResourceStream("SymbolMann.jpg”))
{
    long length = s.Length;
    buffer = new byte[length];
    s.Read(buffer, 0, (int)length);
}
// Do something with buffer

EDIT:

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 called MyCustomPage:

public class MyCustomPage : ContentPage {}

... this is what you would pass: typeof(MyCustomPage)

You need any instance of type Type (this is what the typeof keyword returns basically). The alternative is to call the GetType() 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. calling typeof(ContentPage).GetTypeInfo().Assembly, would return the assembly that the ContentPage 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 the System.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:

Right-click in Xamarin Studio

If the type or method can be resolved, it will show that option.

More on images in Xamarin Forms here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...