WriteableBitmap问题 满分求解

nali29 2010-05-03 07:22:38
我现在有个需求需要把两张大图片合成一张大图片然后根据需求剪切大图成小图:
代码贴下:
WriteableBitmap writeableBitmap = new WriteableBitmap(5100, 1200);
public MainPage()
{
InitializeComponent();
Equipment[0] = 0;
Equipment[1] = 1;
img1.Visibility = Visibility.Collapsed;
img2.Visibility = Visibility.Collapsed;

bi = new BitmapImage(new Uri(@"Images/Body0.png", UriKind.Relative));
bi.ImageOpened += new EventHandler<RoutedEventArgs>(bi_ImageOpened);
//使用一下才会触发ImageOpened事件
img1.Source = bi;
LayoutRoot.Children.Add(img1);


}
Image img1 = new Image();

Image img2 = new Image();
BitmapImage bi;


void bi_ImageOpened(object sender, RoutedEventArgs e)
{
img1.Source = sender as BitmapImage;

writeableBitmap.Render(img1, null);
BitmapImage bi1 = new BitmapImage(new Uri(@"Images/Weapon1.png", UriKind.Relative));
bi1.ImageOpened += new EventHandler<RoutedEventArgs>(bi1_ImageOpened);
img2.Source = bi1;
this.LayoutRoot.Children.Add(img2);


}

Image img = new Image();
void bi1_ImageOpened(object sender, RoutedEventArgs e)
{
img2.Source = sender as BitmapImage;

writeableBitmap.Render(img2, null);
writeableBitmap.Invalidate();
this.img.ImageOpened += new EventHandler<RoutedEventArgs>(img_ImageOpened);
this.img.Source = writeableBitmap;
}
由于要使用WriteableBitmap需要再ImageOpened事件中使用
好,现在我的大图顺利合成成功
定义一个剪切方法
public ImageSource[,] EquipPart(int[] Equipment, int rowNum, int colNum, int singleWidth, int singleHeight)
{



//Equipment[0]为衣服代号,Equipment[1]为武器代号,本例中装备只由衣服+武器组成

//假如内存中没有该装备的角色现成图片源则进行读取

if (PartImage[Equipment[0], Equipment[1]] == null)
{

ImageSource[,] bitmap = new ImageSource[rowNum, colNum];



for (int i = 0; i < rowNum; i++)
{

for (int j = 0; j < colNum; j++)
{
WriteableBitmap wb1 = new WriteableBitmap(singleWidth, singleHeight);
wb1.Render(this.img, new TranslateTransform() { X = -1 * j * singleWidth, Y = -1 * i * singleHeight });
wb1.Invalidate();
bitmap[i, j] = (ImageSource)wb1;


}

}
}
到现在都没有问题
问题出来了
void bi1_ImageOpened(object sender, RoutedEventArgs e)
{
img2.Source = sender as BitmapImage;

writeableBitmap.Render(img2, null);
writeableBitmap.Invalidate();
this.img.ImageOpened += new EventHandler<RoutedEventArgs>(img_ImageOpened);
this.img.Source = writeableBitmap;
EquipPart(Equipment, 8, 34, 150, 150);
}
此时我得到的 bitmap 全部为空图片
思考了好久我猜测错误原因在于 此时的
this.img.Source = writeableBitmap;
这句代码img可能没有真正的加载成功
此时我定义了
this.img.ImageOpened += new EventHandler<RoutedEventArgs>(img_ImageOpened);事件
这个事件只有在下载解析图片的时候才触发 此时我的大图已经在内存中了 所以这个事件 不触发

做了一个另外的试验 我剪切图片放在一个按钮中
private void Button_Click(object sender, RoutedEventArgs e)
{
EquipPart(Equipment, 8, 34, 150, 150);
//此时的bitmap全为成功
}
我现在的需求是一次性执行成功而不是要按钮去实现
...全文
386 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
pojianbing 2010-05-04
  • 打赏
  • 举报
回复
我感觉用WriteableBitmap Render时,只要遵循一定规则就行.Render Image时,要在ImageOpened中进行,Render由 WriteableBitmap 设定Source的Image时(你说的图片已在内存),不要将Image加入VirualTree直接Render就行.
nali29 2010-05-04
  • 打赏
  • 举报
回复
继续等高人
nali29 2010-05-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 pojianbing 的回复:]
虽然不能解决问题,但能够总结几点:
(1) Image的ImageOpened事件只有在加入可视树的情况下(如this.LayoutRoot.Children.Add(img);
),并且在设置Source后触发.
(2) 如果Image的source为WriteableBitmap ,则不触发ImageOpened事件.可能是因为WriteableBitmap本身就在内存.
[/Quote]

谢谢2楼这问题我明白。。。
nali29 2010-05-04
  • 打赏
  • 举报
回复
自己顶起来
blackant2 2010-05-04
  • 打赏
  • 举报
回复
可能是你使用的方式不对,下面是我学习时的代码,功能和你说的应该是一样的,合成图片

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;

namespace SL2WCFAPP.Pages
{
public class WriteableBitmapSample:WrapPanel
{

Image img1 = new Image();
Image img2 = new Image();
Image img=new Image();

int loaded = 0;



public WriteableBitmapSample() {


//创建img1
BitmapImage bi = new BitmapImage(new Uri(@"/Images/001.jpg", UriKind.Relative));
bi.ImageOpened += new EventHandler<RoutedEventArgs>(bi_ImageOpened);
img1.Source = bi;
img1.Width = 100;
img1.Height = 100;
Children.Add(img1);


////创建img2
BitmapImage bi2 = new BitmapImage(new Uri(@"/Images/002.jpg", UriKind.Relative));
bi2.ImageOpened += new EventHandler<RoutedEventArgs>(bi_ImageOpened);
img2.Source = bi2;
img2.Width = 100;
img2.Height = 100;
Children.Add(img2);

//目标
Border border = new Border();
border.BorderBrush = new SolidColorBrush(Colors.Red);
border.BorderThickness = new Thickness(3.0);
border.Child = img;
img.Width = 100;
img.Height = 100;

Children.Add(border);
}



void bi_ImageOpened(object sender, RoutedEventArgs e)
{
loaded += 1;
if (loaded == 2)
{

//由img1先创建一个WriteableBitmap
WriteableBitmap wb = new WriteableBitmap(img1, null);
//将img2通过位移也输出到WriteableBitmap
wb.Render(img2, new TranslateTransform() { X = 50, Y = 50 });
//画布变更后总是要调用
wb.Invalidate();
//可以使用了
img.Source = wb;

}

}

}
}
javalzn 2010-05-04
  • 打赏
  • 举报
回复
当Image的长宽默认为NaN的时候,所做的一切都是无效的。
pojianbing 2010-05-04
  • 打赏
  • 举报
回复
虽然不能解决问题,但能够总结几点:
(1) Image的ImageOpened事件只有在加入可视树的情况下(如this.LayoutRoot.Children.Add(img);
),并且在设置Source后触发.
(2) 如果Image的source为WriteableBitmap ,则不触发ImageOpened事件.可能是因为WriteableBitmap本身就在内存.
nali29 2010-05-03
  • 打赏
  • 举报
回复
需要源码 或sl讨论 +本人QQ 373289508

8,757

社区成员

发帖
与我相关
我的任务
社区描述
WPF/Silverlight相关讨论
社区管理员
  • WPF/Silverlight社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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