2012-11-21 101 views
-1

我已经问你一个问题我的画谜(Original Question)设置为另一个图像。拼图:一个图像相同的大小和位置今天

我开始重写我的代码有更好的表现。我得到了最重要的部分!

但我有一个问题..我产生一个灰色的叠加图像以隐藏图像,而是因为我要处理,我不能为“面具”设置固定的宽度和高度值图片的动态大小。所以可能不是全部图片都覆盖了我的“面具”。

是否有人对此有一个解决方案吗?我不知道如何根据图片的位置和大小来确定我的面具的位置和大小。

我连着示范截屏。

XAML:

<Window x:Class="PicturePuzzle.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" 
     Loaded="WindowLoaded"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*" /> 
      <RowDefinition Height="80" /> 
     </Grid.RowDefinitions> 

     <Grid x:Name="grid" 
       Margin="5" 
       HorizontalAlignment="Center" 
       VerticalAlignment="Top"> 

      <Image x:Name="imgPicture" 
        HorizontalAlignment="Stretch" 
        VerticalAlignment="Stretch" 
        Source="Images/puzzle.gif" 
        Stretch="Uniform" /> 
      <Image x:Name="imgMask" RenderOptions.EdgeMode="Aliased" /> 
     </Grid> 

     <StackPanel Grid.Row="1" 
        HorizontalAlignment="Center" 
        VerticalAlignment="Center"> 
      <StackPanel Margin="0,0,0,10" Orientation="Horizontal"> 
       <Button x:Name="btnStart" 
         Width="60" 
         Margin="0,0,5,0" 
         Click="BtnStartClick" 
         Content="Start" /> 
       <Button x:Name="btnStop" 
         Width="60" 
         Click="BtnStopClick" 
         Content="Stop" 
         IsEnabled="False" /> 
       <ToggleButton x:Name="btnSolution" 
           Margin="5,0,0,0" 
           Checked="btnSolution_Checked" 
           Content="Lösung anzeigen" 
           Unchecked="btnSolution_Unchecked" /> 
      </StackPanel> 
      <Slider x:Name="slSpeed" 
        IsDirectionReversed="True" 
        Maximum="10" 
        Minimum="1" 
        ValueChanged="SlSpeedValueChanged" 
        Value="10" /> 
     </StackPanel> 
    </Grid> 
</Window> 

代码隐藏:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Windows; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Threading; 

namespace PicturePuzzle 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      _positionAlphaValues = new Dictionary<Point, byte>(); 

      _images = new List<FileInfo>(); 
      using (var s = new StreamReader("Images.txt")) 
      { 
       while (!s.EndOfStream) 
       { 
        var line = s.ReadLine(); 

        if (string.IsNullOrWhiteSpace(line)) 
        { 
         continue; 
        } 

        var fi = new FileInfo(line); 

        if (!fi.Exists) 
        { 
         continue; 
        } 

        _images.Add(fi); 
       } 
      } 
     } 

     private const int MaxQuadsX = 5; 
     private const int MaxQuadsY = 5; 

     private readonly List<FileInfo> _images; 

     private DispatcherTimer _timer; 
     private DispatcherTimer _alphaTimer; 
     private WriteableBitmap _bitmap; 
     private Size _size; 
     private List<Point> _positions; 
     private Dictionary<Point, byte> _positionAlphaValues; 
     private int _tickCounter; 
     private int _imageCounter; 
     private int _quadWidth; 
     private int _quadHeight; 


     private void WindowLoaded(object sender, RoutedEventArgs e) 
     { 
      _size = imgPicture.RenderSize; 

      var width = (int)Math.Ceiling(_size.Width); 
      var height = (int)Math.Ceiling(_size.Height); 

      _quadWidth = width/MaxQuadsX; 
      _quadHeight = height/MaxQuadsY; 

      imgPicture.Width = _quadWidth * MaxQuadsX - 5; 
      imgPicture.Height = _quadHeight * MaxQuadsY - 5; 

      _bitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null); 

      imgMask.Source = _bitmap; 
     } 

     #region Click handlers 

     private void BtnStartClick(object sender, RoutedEventArgs e) 
     { 
      btnStart.IsEnabled = false; 
      btnStop.IsEnabled = true; 
      btnSolution.IsChecked = false; 

      // set the real picture 
      _imageCounter = 0; 
      _images.Shuffle(); 
      SetPuzzlePicture(); 

      _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(slSpeed.Value/10) }; 
      _timer.Tick += TimerTick; 
      _timer.Start(); 

      _alphaTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.1) }; 
      _alphaTimer.Tick += AlphaTimerOnTick; 
      _alphaTimer.Start(); 
     } 

     private void BtnStopClick(object sender, RoutedEventArgs e) 
     { 
      btnStart.IsEnabled = true; 
      btnStop.IsEnabled = false; 

      _timer.Stop(); 
      _alphaTimer.Stop(); 
     } 

     private void SlSpeedValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) 
     { 
      if (_timer != null) 
      { 
       _timer.Interval = TimeSpan.FromSeconds(slSpeed.Value/10); 
      } 
     } 


     private void btnSolution_Checked(object sender, RoutedEventArgs e) 
     { 
      btnStop.IsEnabled = false; 

      StopTimers(); 

      imgMask.Visibility = Visibility.Hidden; 
     } 

     private void btnSolution_Unchecked(object sender, RoutedEventArgs e) 
     { 
      btnStart.IsEnabled = true; 
      btnStop.IsEnabled = false; 

      ResetMaskImage(); 
     } 

     #endregion 

     private void SetPuzzlePicture() 
     { 
      _positionAlphaValues.Clear(); 

      ResetMaskImage(); 

      var imgFile = _images[_imageCounter++]; 

      var image = new BitmapImage(); 
      image.BeginInit(); 
      image.UriSource = new Uri(imgFile.FullName, UriKind.Absolute); 
      image.EndInit(); 

      imgPicture.Source = image; 
     } 

     private void TimerTick(object sender, EventArgs e) 
     { 
      if (_tickCounter >= _positions.Count) 
      { 
       if (_imageCounter >= _images.Count) 
       { 
        _timer.Stop(); 

        btnStart.IsEnabled = true; 
        btnStop.IsEnabled = false; 

        return; 
       } 

       SetPuzzlePicture(); 
      } 

      var randomPoint = _positions[_tickCounter++]; 

      _positionAlphaValues.Add(randomPoint, 255); 
     } 

     private void AlphaTimerOnTick(object sender, EventArgs eventArgs) 
     { 
      var updatedList = new Dictionary<Point, byte>(); 

      foreach (var e in _positionAlphaValues) 
      { 
       var newValue = e.Value - (11 - slSpeed.Value) * 5; 

       if (newValue <= 0) 
       { 
        continue; 
       } 

       SetAlphaChannel(e.Key, (byte)newValue); 
       updatedList.Add(e.Key, (byte)newValue); 
      } 

      _positionAlphaValues = updatedList; 
     } 

     private void StopTimers() 
     { 
      if (_timer != null) 
      { 
       _timer.Stop(); 
      } 

      if (_alphaTimer != null) 
      { 
       _alphaTimer.Stop(); 
      } 
     } 

     private void ResetMaskImage() 
     { 
      imgMask.Visibility = Visibility.Visible; 

      var width = _quadWidth * MaxQuadsX; 
      var height = _quadHeight * MaxQuadsY; 
      var size = width * height * 4; 

      var buffer = new byte[size]; 

      for (int i = 0; i < size; i++) 
      { 
       buffer[i++] = 128; 
       buffer[i++] = 128; 
       buffer[i++] = 128; 
       buffer[i] = 255; 
      } 

      var area = new Int32Rect(0, 0, width, height); 
      _bitmap.WritePixels(area, buffer, width * 4, 0); 

      _positions = GetPositions(); 
      _tickCounter = 0; 
     } 

     private void SetAlphaChannel(Point point, byte alpha) 
     { 
      var size = _quadWidth * _quadHeight * 4; 
      var buffer = new byte[size]; 

      for (int i = 0; i < size; i++) 
      { 
       buffer[i++] = 128; 
       buffer[i++] = 128; 
       buffer[i++] = 128; 
       buffer[i] = alpha; 
      } 

      var startX = (int)point.X * _quadWidth; 
      var startY = (int)point.Y * _quadHeight; 

      var area = new Int32Rect(startX, startY, _quadWidth, _quadHeight); 
      _bitmap.WritePixels(area, buffer, _quadWidth * 4, 0); 
     } 

     private List<Point> GetPositions() 
     { 
      var generated = new List<Point>(); 

      for (int y = 0; y < MaxQuadsY; y++) 
      { 
       for (int x = 0; x < MaxQuadsX; x++) 
       { 
        var point = new Point(x, y); 

        generated.Add(point); 
       } 
      } 

      generated.Shuffle(); 

      return generated; 
     } 
    } 
} 

Extensions.cs

using System; 
using System.Collections.Generic; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 

namespace PicturePuzzle 
{ 
    public static class Extensions 
    { 
     public static Color GetPixel(this WriteableBitmap wbm, int x, int y) 
     { 
      if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1) 
       return Color.FromArgb(0, 0, 0, 0); 

      if (y < 0 || x < 0) 
       return Color.FromArgb(0, 0, 0, 0); 

      if (!wbm.Format.Equals(PixelFormats.Bgra32)) 
       return Color.FromArgb(0, 0, 0, 0); 

      IntPtr buff = wbm.BackBuffer; 
      int stride = wbm.BackBufferStride; 
      Color c; 

      unsafe 
      { 
       var pbuff = (byte*)buff.ToPointer(); 
       int loc = y * stride + x * 4; 

       c = Color.FromArgb(
        pbuff[loc + 3], 
        pbuff[loc + 2], pbuff[loc + 1], 
        pbuff[loc]); 
      } 

      return c; 
     } 

     public static void Shuffle<T>(this IList<T> list) 
     { 
      var rng = new Random(); 
      int n = list.Count; 
      while (n > 1) 
      { 
       n--; 
       int k = rng.Next(n + 1); 
       T value = list[k]; 
       list[k] = list[n]; 
       list[n] = value; 
      } 
     } 
    } 
} 

例Images.txt(必须是在输出文件夹,该图像也):

Desert.jpg 
Hydrangeas.jpg 
Jellyfish.jpg 
Koala.jpg 
Lighthouse.jpg 
Penguins.jpg 
Tulips.jpg 
androids.gif 
Chrysanthemum.jpg 

而截屏视频:Screencast Link

感谢您的帮助!

回答

2

您可以设置HorizontalAlignment和你的面具形象VerticalAlignmentStretchStretch来填补像这样:

<Image HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="imgMask" Stretch="Fill" RenderOptions.EdgeMode="Aliased" />

这将导致面膜图像填补了网格,将尺寸另一张图片。

+0

嘿,面具现在有网/窗的整个规模(预计在底部的80个像素的控制栏,但正是这就是我想要的)。但是imgPicture的大小不一样,也没有调整大小。试着将它设置为imgPicture的Stretch to Fill and Uniform。最好的解决方案是,如果Mask具有Stretch =“Uniform”的imgPicture的尺寸。 –

相关问题