WPF下,将图片作为resource生成后能不能像IO访问路径一样读取

wly880601 2012-02-23 12:25:48
当前的代码:
方法1
<!--数据字典中,类似的Image有200多个-->
<ResourceDictionary x:Class="MineRecipes.MineDictionary"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Image x:Shared="False" x:Key="small" Source="/MineRecipes;component/Imgs/BackGround/Grid_layout_None_%28small%29.png"/>
<!--前台XAML的绑定,可以正常访问-->
<Border Grid.Column="0" Grid.Row="0" Child="{StaticResource ResourceKey=small}" />

方法2
//后台代码
//通过IO获取程序目录下Imgs文件夹内的所有文件
string[] strRecipes = Directory.GetFiles("..\\..\\Imgs");
foreach (var v in strRecipes)
{
if (!v.ToLower().EndsWith(".png", StringComparison.CurrentCulture)) continue;//过滤器

string ImgPath = _strPath + "\\" + v;//Imgs下所有png的全路径
Image img = new Image() { Source = new BitmapImage(new Uri(ImgPath)), Stretch = Stretch.None };
stkRecipes.Children.Add(img);//加进一个StackPanel
}


这里我想问的是,如果用我现在的代码,最后生成可执行文件外必须另外附带一个Imgs的文件夹才能在方法2中正常读取图片,而方法1则只需要一个EXE就能正常读取图片了
请问有没有人办法如方法1一样访问在程序中嵌入的资源图片?最好能和IO一样一次读取所有图片!万分感谢
...全文
379 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
愚心少年一只 2012-02-23
  • 打赏
  • 举报
回复
厉害
厉害
厉害厉害

wly880601 2012-02-23
  • 打赏
  • 举报
回复
谢谢,正在看。。
nonocast 2012-02-23
  • 打赏
  • 举报
回复
前台的绑定

book.Open();
foreach (var each in book) {
if (first == null) { first = each; }
Image image = new Image();
image.Tag = each;
image.MouseDown += new MouseButtonEventHandler(image_MouseDown);
image.Source = each.ImageSource;

Binding binding = new Binding("ImageSource");
binding.Source = each;
image.SetBinding(Image.SourceProperty, binding);


image.Stretch = Stretch.Uniform;
WrapPanel1.Children.Add(new Border { BorderThickness = new Thickness(1), BorderBrush = Brushes.DarkGray, Child = image });
}

xaml就是个壳子

<ScrollViewer>
<WrapPanel x:Name="WrapPanel1" Margin="10, 5">
<WrapPanel.Resources>
<Style TargetType="Border">
<Setter Property="Width" Value="300" />
<Setter Property="Height" Value="370" />
<Setter Property="Margin" Value="5,3" />
</Style>
<Style TargetType="Image">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
</Style>
</WrapPanel.Resources>
</WrapPanel>
</ScrollViewer>
nonocast 2012-02-23
  • 打赏
  • 举报
回复
随手有一个Test你参考一下,不过你的图片很小就另说了,即使很小你要注意区分encode/decode的大小是不同的,encode指jpg,decode后是bitmap会大N倍,你有200个icon?so many!

测试代码,仅供参考

public class Book : ObservableCollection<Page> {
public void Open() {
string sampleFolder = @"C:\Users\nonocast.DEV.000\Desktop\BookSolution\Sample - 副本";
int i = 0;
foreach (var each in Directory.GetFiles(sampleFolder)) {
this.Add(new Page(i++, each));
}
}

public void Load(Page page) {
if (cache.Contains(page)) return;

if (cache.Count >= 3) {
cache.Dequeue().BeginLoadLowQuality();
}
page.BeginLoad();
cache.Enqueue(page);
}

private Queue<Page> cache = new Queue<Page>();
}

public class Page : DependencyObject {
public int Index { get; private set; }
public string ImagePath { get; private set; }
public BitmapImage ImageSource {
get { return (BitmapImage)GetValue(ImageSourceProperty); }
set { SetValue(ImageSourceProperty, value); }
}

public static readonly DependencyProperty ImageSourceProperty =
DependencyProperty.Register("ImageSource", typeof(BitmapImage), typeof(Page), new UIPropertyMetadata(null));

public Page(int index, string imagePath) {
this.Index = index;
this.ImagePath = imagePath;
this.ImageSource = defaultImage;
}

private BitmapImage GetLowQualityImage() {
BitmapImage result = null;
if (lowQualityImage == null) {
result = new BitmapImage();
result.BeginInit();
result.StreamSource = new MemoryStream(File.ReadAllBytes(ImagePath));
result.CacheOption = BitmapCacheOption.OnLoad;
result.DecodePixelWidth = 100;
result.EndInit();
lowQualityImage = result;
} else {
result = lowQualityImage;
}
return result;
}

static Page() {
var ms = new MemoryStream(File.ReadAllBytes(@"Resources\blank.jpg"));
defaultImage = new BitmapImage();
defaultImage.BeginInit();
defaultImage.CacheOption = BitmapCacheOption.OnLoad;
defaultImage.StreamSource = ms;
defaultImage.EndInit();
}

public void BeginLoad() {
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = new MemoryStream(File.ReadAllBytes(ImagePath));
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
ImageSource = bitmap;
}

public void BeginLoadLowQuality() {
ImageSource = GetLowQualityImage();
}

private BitmapImage lowQualityImage;
private static BitmapImage defaultImage;
}
wly880601 2012-02-23
  • 打赏
  • 举报
回复
谢谢nonocast的热心回答, 话说昨天好像就是你告诉我怎么读图片的

其实我现在已经把图片放在Resource里面了,静态读取那部分(图中右边的小妹妹和界面的框)已经通过XAML实现了,现在就是想用C#的后台代码实现动态读取(或者读取副本)来切换图片

由于图片已经加进EXE了,现在就是加进EXE的200来张图片让一个人读和让很多人一起读的区别

况且现在打包好的程序加上图片也才900KB

所以就想请教一下怎么用C#读Resource里面的图片
nonocast 2012-02-23
  • 打赏
  • 举报
回复
放到Resources里面去,
具体操作就是在Solution中新建一个Resources的目录,然后把图片copy过去,设置为Resources即可

其实不推荐嵌入,搞得exe很大,而且一样可以获取出来,推荐的做法是把图片就放在那里
如果你实在不爽,那么就用System.IO.Packaging把所有图片打包成一个单独的文件,形成一个Resource
或者把resources做成一个单独的dll

很多方法,不过把图片放到exe里面算下策
wly880601 2012-02-23
  • 打赏
  • 举报
回复

发图解释得清楚些
wly880601 2012-02-23
  • 打赏
  • 举报
回复
真巧,我做的静态那部分就是看这篇文章做出来的

可是我现在遇到的问题这里没有提到,就是怎么样获取相对路径images文件夹里的所有文件
nonocast 2012-02-23
  • 打赏
  • 举报
回复
你的情况你自己最清楚,嘿嘿
Take it easy. good luck.
wly880601 2012-02-23
  • 打赏
  • 举报
回复
恩谢谢,我先去看看你发的博文
wly880601 2012-02-23
  • 打赏
  • 举报
回复
Application.GetResourceStream(new Uri("images/winter.jpg", UriKind.Relative));
这个是已经知道图片的名字了

能不能在不知道图片名字的情况下,一次获取所有的images文件夹下的所有东西?就像IO的Directory.GetFiles("..\\..\\Imgs") 那样

200多张名字,一个个手输会死人的
wly880601 2012-02-23
  • 打赏
  • 举报
回复
啊太感谢了,要的就是这个
nonocast 2012-02-23
  • 打赏
  • 举报
回复
Application.GetResourceStream(new Uri("images/winter.jpg", UriKind.Relative));
nonocast 2012-02-23
  • 打赏
  • 举报
回复
至于GetValue/SetValue属于Dependency Property概念
DP是对传统属性的对象化(objectable),WPF几个核心概念包括Binding,Tempalte,Style,RoutedEvent,Command都是基于DP,所以看下DP先。
基于初学,推荐你看WPF编程宝典作为入门,然后看CP的Applications = Code + Markup
不看书不行啊。。。
wly880601 2012-02-23
  • 打赏
  • 举报
回复
还有就是,如果我没理解错的话这个这段代码读取的是绝对路径“C:\Users\nonocast.DEV.000\Desktop\BookSolution\Sample - 副本”中的图片吧?
这个功能我已经实现了,我现在想要的是读取在程序中“藏”着的200张png图标,不知道这个该如何实现呢?还是你的代码里面就有,但是我没看出来?
nonocast 2012-02-23
  • 打赏
  • 举报
回复
image.Source = each.ImageSource;这里是给图片绑定资源
这句删掉,测试用的
下面才是绑定,
Binding binding = new Binding("ImageSource");
binding.Source = each;
image.SetBinding(Image.SourceProperty, binding);
绑定的优势在于Page的ImageSource变化后会联动UI上的Image自动更新
wly880601 2012-02-23
  • 打赏
  • 举报
回复
nonocast你好
在你的代码中
image.Source = each.ImageSource;这里是给图片绑定资源
然后Book类下子集Page的ImageSource 返回的是 get { return (BitmapImage)GetValue(ImageSourceProperty); }
这里我就找不到GetValue这个方法在哪了……
我才接触WPF没多久,有什么不对的请指正,谢谢

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧