4

実行時に CroppedBitmap の SourceRect プロパティを変更しようとしても、何も起こりません。エラーは発生せず、プロパティ値は実際には変更されません。

スプライトアニメーションを作ろうとしています。スプライトシートを含む BitmapSource があります。これは、スプライトのさまざまなポーズのグリッドを含む単一のビットマップです。次に、ソースとしてスプライト シートを持つ CroppedBitmap と、スプライト シートからポーズの 1 つを引き出す SourceRect があります。実行時にアニメーション化する必要がある場合は、CroppedBitmap の SourceRect プロパティを変更して、より大きなビットマップから別のポーズを引き出します。しかし、上で述べたように、新しいプロパティ値は単純に固執しません。それは最も奇妙なことです。

XAML のサンプルを次に示します。

<UserControl.Resources>
    <BitmapImage x:Key="spritesheet" UriSource="Sprites/elf.png"/>
</UserControl.Resources>
<Image>
    <Image.Source>
        <CroppedBitmap x:Name="image" Source="{StaticResource spritesheet}"
                       SourceRect="240 640 240 320"/>
    </Image.Source>
</Image>

そしてコードビハインドはこれをしようとします:

var newRect = new Int32Rect(...);
Debug.WriteLine("             Before: " + image.SourceRect);
Debug.WriteLine("Assigning new value: " + newRect);
image.SourceRect = newRect;
Debug.WriteLine("              After: " + image.SourceRect);

これにより、次のデバッグ出力が得られます。

             Before: 240,640,240,320
Assigning new value: 240,0,240,320
              After: 240,640,240,320

つまり、実際には新しい四角形 (Y=0) をプロパティに割り当てています。例外はありません。しかしその後、プロパティ値はまったく変化しませんでした (Y は 640 のままです)。

なぜこれが起こるのか、そしてそれを修正する方法についてのアイデアはありますか?

4

3 に答える 3

6

これに対処する別の方法は次のとおりです。
を使用する代わりにCroppedBitmap、完全なソース画像を使用しますが、次のようになります。

  1. を設定しimage.RenderTransformて、表示領域を調整します。
  2. Image.Clip画像の不要な部分が表示されないように、必要に応じて設定します。

これは、新しいものを作り続ける必要がなくCroppedBitmaps、変換を調整するだけでよいことを意味します。
私のテストでは、どちらの方法でも速度に違いは見られませんでした。

完全を期すために、私が提案していることを実行するためにコードを調整する方法は次のとおりです。

<Image RenderTransform="1, 0, 0, 1, -240, -640">
  <!-- Still include your Image.Source here, just not as a CroppedBitmap -->
  <Image.Clip>
    <RectangleGeometry Rect="0, 0, 240, 320" />
  </Image.Clip>
</Image>

次に、調整と同等のことを行うための後での呼び出しSourceRectは次のとおりです。

image.RenderTransform = new MatrixTransform(1d, 0d, 0d, 1d, -240d, 0d);
于 2011-07-25T14:31:35.240 に答える
0

を使用する方法は次のIMultiValueConverterとおりです。

<Image>
    <Image.Source>
        <MultiBinding Converter="{x:Static local:SourceAndRectToCroppedBitmapConverter.Default}">
            <Binding Path="FileName" />
            <Binding Path="CropRect" />
        </MultiBinding>
    </Image.Source>

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;

public class SourceAndRectToCroppedBitmapConverter : IMultiValueConverter
{
    public static readonly SourceAndRectToCroppedBitmapConverter Default = new SourceAndRectToCroppedBitmapConverter();

    private static readonly ImageSourceConverter Converter = new ImageSourceConverter();

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values[0] is string text)
        {
            return new CroppedBitmap((BitmapSource)Converter.ConvertFrom(values[0]), (Int32Rect)values[1]);
        }

        return new CroppedBitmap((BitmapSource)values[0], (Int32Rect)values[1]);
    }

    object[] IMultiValueConverter.ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

パフォーマンスが低い可能性があります。

于 2017-06-01T09:29:39.287 に答える