Fre*_*ger 6 c# image xamarin xamarin.forms
我有一个(希望)简单的问题(我没有找到答案,这符合我所有的搜索).
我使用Xamarin.Forms 1.4.1-Pre-1.在我的应用程序中,我有:
byte[] AvatarErfassung; // Bytearray, to later update the webservice
var Avatar = new Image { HeightRequest = 71, WidthRequest = 61, HorizontalOptions = LayoutOptions.Start };
Avatar.Source = "SymbolMann.jpg";
Run Code Online (Sandbox Code Playgroud)
其中图像"SymbolMann.jpg" 作为项目资源(在每个项目中)包含在页面上(没有问题).
我现在想把图像放在一个字节数组中,然后发送到我们的web服务.找不到任何方法来访问图像"SymbolMann.jpg"(以字节数组加载)或使用(但是)Avatar.Source.
问题:
如何将图像"SymbolMann.jpg"放入字节数组"AvatarErfassung"中?
谢谢你的每一个答案
嗨迪米特里斯
感谢您的(快速)重播.
正如我写的那样,我和Xamarin一起工作.表格.
图像存储为资源:在\ Resources\Drawable \(对于Android),\ Resources \(对于iOS)和根(对于WP).我必须在内容页面上加载图像.
如果我超越你的代码,就行:
var assembly = this.GetType().GetTypeInfo().Assembly;
Run Code Online (Sandbox Code Playgroud)
我有错误消息(翻译成英文):
"System.Type不包含GetTypeInfo方法的定义(使用丢失?)"
我是否必须添加特定的使用?
您编写://您可以将"this.GetType()"替换为"typeof(MyType)",其中MyType是程序集中的任何类型.
我有什么要作为类型放置?
= typeof(????).GetTypeInfo().程序集:
感谢您的进一步回复.
更新#2:
第一,谢谢你的耐心......
不幸的是在VS2013中,我没有找到任何显示我缺少使用的功能"解析" - 但我发现了使用我自己的缺失:-)
同时我添加了使用System.Reflection;
现在,行:var assembly = this.GetType().GetTypeInfo().Assembly;
解决和编译没有错误
此外,我已将.jpg的类型从"Android资源"更改为"嵌入式资源".
然后应用程序在行中崩溃:long length = s.Length;
因为它似乎是null(我认为没有找到jpg)
此外 - 如果我将类型更改为"嵌入式资源" - Xamarin.Forms(Avatar.Source ="SymbolMann.jpg";)不再找到图像
如果我将.jpg的类型更改为"编译",我无法编译应用程序.
错误消息:命名空间不能直接包含字段或方法等成员.
那么...资源的正确类型是什么(因此可以使用assembly.GetManifestResourceStream()加载它?
我是否必须在文件名中添加一些内容(SymbolMann.jpg)才能找到它?
我如何更改Avatar.Source ="SymbolMann.jpg"以便找到它(如果我将类型从"Android资源"更改为其他任何内容)?
我的需求再一次:
在注册页面上,默认图像(符号)在标准Xamarin.Forms图像中显示为男人和女人的化身(avatar.source ="SymbolMann.jpg"/"SymbolFrau.jpg") .
.jpg存储在每个项目(Android,iOS和WP)的标准目录中,可以在没有图像对象问题的情况下访问它们.
然后,用户可以使用其中一个默认图像或通过mediapicker加载另一个默认图像.
如果用户点击"注册"按钮,我必须从Image创建一个字节数组,通过json将其发送到我们的webservice.
如果用户通过mediapicker选择另一个图像,我可以访问流,问题是,从默认图像(在每个平台中)成为字节数组.
再次感谢您的帮助......
Dim*_*kos 12
您可以通过从程序集中读取资源流来轻松完成此操作:
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
Run Code Online (Sandbox Code Playgroud)
编辑:
要获取包含项目的嵌入资源的程序集,您需要GetTypeInfo在该程序集中包含的类型上调用该方法.因此,typeof(X)"X"是装配中的任何类型.例如,如果您使用的是名为的自定义页面MyCustomPage:
public class MyCustomPage : ContentPage {}
Run Code Online (Sandbox Code Playgroud)
......这就是你要通过的: typeof(MyCustomPage)
您需要任何类型的实例Type(这是typeof关键字基本返回的内容).另GetType()一种方法是在项目中包含的任何对象上调用该方法.
请注意,如果调用typeof(X)项目中未包含的类型,则无法获得正确的程序集.例如.调用typeof(ContentPage).GetTypeInfo().Assembly,将返回该ContentPage类型所在的程序集.哪个不包含您的资源.我希望这不会令人困惑.如果是,请告诉我.
现在,该GetTypeInfo方法是包含在System.Reflection命名空间中的扩展方法.当Xamarin Studio中的文本编辑器无法识别某些内容时,它会用红色突出显示它.右键单击它将在上下文菜单中为您提供Resolve选项:

如果可以解析类型或方法,它将显示该选项.
更多关于在Xamarin形成图像这里.
首先,非常感谢Dimitris指导我走向正确的方向!
结论:
基础:
我使用VS2013 - 更新2,Xamarin.Forms(1.4.1-Pre1),我的应用程序基于模板"空白应用程序(Xamarin.Forms共享)"(不是PCL),我使用所有平台(Android ,iOS,WP).
在用户注册页面上,用户可以选择图像作为化身(稍后显示给他的帖子).根据用户的性别,有两个默认图像(一个用于男性,一个用于女性).然后,用户可以超过其中一个默认图像或从媒体选择器中选择另一个图像.
默认图像存储在内容图像的默认位置(对于Android,例如在/ Resources/Drawable /下).
图像显示在XF-Standard-Image-Object中,Image-Source ="xxx.jpg".
这没有问题.
问题:
由于用户数据(包括头像)存储在SQL-Server上(通过Json-web-service),我必须将图像数据转换为字节数组(然后将其与另一个一起发送)数据作为Web服务的字符串).
问题是,从默认目录加载图像并将其转换为字节数组(由此文件访问是问题 - >无法访问).
解决方案:
感谢Dimitris,我指导了我正确的方向,我实施了以下解决方案:
在所有项目(Android,iOS和WP)中,我添加了一个新目录"\ Embedded \"(直接位于根目录下).然后,我在这个目录中复制了我的两个jpg("SymbolMann.jpg"和"SymbolFrau.jpg")(对于所有平台).
然后,我将资源类型更改为从"AndroidResource"到"Embedded "的图像资源"(适用于所有类型的平台).
在我的应用程序启动代码(app.cs)中,我添加了:
//
string cNameSpace = "";
switch (Device.OS)
{
case TargetPlatform.WinPhone:
cNameSpace = "MatrixGuide.WinPhone";
break;
case TargetPlatform.iOS:
cNameSpace = "MatrixGuide.iOS";
break;
case TargetPlatform.Android:
cNameSpace = "MatrixGuide.Droid";
break;
}
GV.cEmbeddedAblage = cNameSpace + ".Embedded.";
Run Code Online (Sandbox Code Playgroud)
其中GV.cEmbeddedAblage只是一个全局变量.
要检查命名空间名称,我必须右键单击每个平台的项目,并查看已确定的命名空间名称(可能在您的项目中有所不同).
.Embedded.是新创建的目录(在所有平台上都是相同的名称).
另外,我为男性图像(GV.ByteSymbolMann)和女性图像(GV.ByteSymbolFrau)创建了全局字节数组.
在注册页面的启动代码中,我添加了:
string cFilename = "";
if (GV.ByteSymbolMann == null) // not yet loaded
{
cFilename = GV.cEmbeddedAblage + "SymbolMann.jpg";
var assembly = this.GetType().GetTypeInfo().Assembly;
byte[] buffer;
using (Stream s = assembly.GetManifestResourceStream(cFilename))
{
long length = s.Length;
buffer = new byte[length];
s.Read(buffer, 0, (int)length);
GV.ByteSymbolMann = buffer; // Overtake byte-array in global variable for male
}
}
//
if (GV.ByteSymbolFrau == null) // not yet loaded
{
cFilename = GV.cEmbeddedAblage + "SymbolFrau.jpg";
var assembly = this.GetType().GetTypeInfo().Assembly;
byte[] buffer;
using (Stream s = assembly.GetManifestResourceStream(cFilename))
{
long length = s.Length;
buffer = new byte[length];
s.Read(buffer, 0, (int)length);
GV.ByteSymbolFrau = buffer; // Overtake byte-array in global variable for female
}
}
Run Code Online (Sandbox Code Playgroud)
将.jpg加载到图像对象的代码,我不得不改为:
//Avatar.Source = "SymbolMann.jpg"; // Load from default directory
Run Code Online (Sandbox Code Playgroud)
至
Avatar.Source = ImageSource.FromStream(() => new MemoryStream(GV.ByteSymbolMann)); // Load (stream) from byte-array
Run Code Online (Sandbox Code Playgroud)
然后我在另一个字节数组中接管选定的字节数组(并行显示图像)(以便稍后以字符串形式上传到Web服务)
AvatarErfassung = GV.ByteSymbolMann;
Run Code Online (Sandbox Code Playgroud)
如果用户更改选择(例如,更改为女性):
Avatar.Source = ImageSource.FromStream(() => new MemoryStream(GV.ByteSymbolFrau));
AvatarErfassung = GV.ByteSymbolFrau;
Run Code Online (Sandbox Code Playgroud)
注意:如果用户从mediapicker中选择另一个图像,我可以直接访问该流,因此这绝不是问题所在.
此解决方案适用于所有平台(Android,iOS,WP).
我希望这可以帮助其他一些用户...
而且......最后还要感谢Dimitris
谢谢@FredWenger和@Dimitris - 这是我的解决方案,基于你的答案:
MyProject\DaffyDuck.jpgEmbedded Resource(文件属性 - >构建操作)ImageDataFromResource("MyProject.DaffyDuck.jpg")这是功能:
public byte[] ImageDataFromResource(string r)
{
// Ensure "this" is an object that is part of your implementation within your Xamarin forms project
var assembly = this.GetType().GetTypeInfo().Assembly;
byte[] buffer = null;
using (System.IO.Stream s = assembly.GetManifestResourceStream(r))
{
if (s != null)
{
long length = s.Length;
buffer = new byte[length];
s.Read(buffer, 0, (int)length);
}
}
return buffer;
}
Run Code Online (Sandbox Code Playgroud)如果需要在ImageView控件中引用加载的数据,请执行以下操作:
ImageView.Source = ImageSource.FromStream(() => new MemoryStream(imageData));
*注意:如果步骤3不起作用并且您想检查嵌入的资源名称,请调用:var names = assembly.GetManifestResourceNames();并查看项目中列出的内容.
添加到noelicus 的答案:
将图像添加到 Xamarin.Forms 项目的根文件夹中,例如MyProject\pizza.png
在 Visual Studio 中,右键单击图像文件并选择Build Action->EmbeddedResource
public byte[] GetImageFromFile(string fileName)
{
var applicationTypeInfo = Application.Current.GetType().GetTypeInfo();
byte[] buffer;
using (var stream = applicationTypeInfo.Assembly.GetManifestResourceStream($"{applicationTypeInfo.Namespace}.fileName"))
{
if (stream != null)
{
long length = stream.Length;
buffer = new byte[length];
stream.Read(buffer, 0, (int)length);
}
}
return buffer;
}
Run Code Online (Sandbox Code Playgroud)
public class MyPage() : ContentPage
{
public MyPage()
{
var imageAsByteArray = GetImageFromFile("pizza.png");
var pizzaImage = new Image();
pizzaImage.Source = ImageSource.FromStream(() => new MemoryStream(imageAsByteArray));
Content = pizzaImage;
}
byte[] GetImageFromFile(string fileName)
{
var applicationTypeInfo = Application.Current.GetType().GetTypeInfo();
byte[] buffer;
using (var stream = applicationTypeInfo.Assembly.GetManifestResourceStream($"{applicationTypeInfo.Namespace}.{fileName}"))
{
if (stream != null)
{
long length = stream.Length;
buffer = new byte[length];
stream.Read(buffer, 0, (int)length);
}
}
return buffer;
}
}
Run Code Online (Sandbox Code Playgroud)