1

SilverlightでBitmapImageを変更しようとしていますが、たまたま「壊滅的な障害」が発生しました。

まず、画像を読み込んでLayoutRootに追加します。

BitmapImage source = new BitmapImage(new Uri("image.jpg", UriKind.Relative));
Image imageElement = new Image();
imageElement.Name = "imageElement";
imageElement.Source = source;
imageElement.Stretch = Stretch.None;
LayoutRoot.Children.Add(imageElement);

これは正常に機能し、画像は画面に正しく表示されます。

次に、画像を変更します(たとえば、ボタンをクリックした後)。

ボタンクリックメソッドでは、最初にLayoutRootから画像を取得し、次にWriteableBitmapクラスを使用して画像を変更します。

Image imageElement = (Image) LayoutRoot.Children[1];
WriteableBitmap writeableBitmap = new WriteableBitmap(imageElement, null);
writeableBitmap.ForEach((x,y,color) => Color.FromArgb((byte)(color.A / 2), color.R, color.G, color.B));

次に、指定された方法を使用してバイト配列バッファーに保存します。

byte[] buffer = writeableBitmap.ToByteArray();  

これもよさそうだ。バッファにはすべてのARGB値が表示され、アルファ値でさえ通常の値の半分である127です。

次のステップでは、変更したデータをBitmapImageにロードし、最後にImageにロードして、LayoutRootに再度追加します。

BitmapImage modifiedSource = null;
try
{
    using (MemoryStream stream = new MemoryStream(buffer))
    {
        stream.Seek(0, SeekOrigin.Begin);
        BitmapImage b = new BitmapImage();
        b.SetSource(stream);
        modifiedSource = b;
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString());
}

私はここでこのコードピースを見つけました:byte[]からBitmapImageへのsilverlight

最後のステップとして、イメージを再度作成し、それをLayoutRootに追加します(最初に行ったのと同じように:

Image modifiedImageElement = new Image();
modifiedImageElement.Name = "newImageElement";
modifiedImageElement.Source = modifiedSource;
modifiedImageElement.Stretch = Stretch.None;
LayoutRoot.Children.Add(modifiedImageElement);

しかし、「壊滅的な障害」が発生するため、最後の部分に到達することはありません。

b.SetSource(stream);

行、言って:

{System.Exception: Catastrophic failure (Ausnahme von HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
   at MS.Internal.XcpImports.BitmapSource_SetSource(BitmapSource bitmapSource, CValue& byteStream)
   at System.Windows.Media.Imaging.BitmapSource.SetSourceInternal(Stream streamSource)
   at System.Windows.Media.Imaging.BitmapImage.SetSourceInternal(Stream streamSource)
   at System.Windows.Media.Imaging.BitmapSource.SetSource(Stream streamSource)
   at SilverlightApplication1.MainPage.button1_Click(Object sender, RoutedEventArgs e)}

何が悪かったのかわかりません。ここでSilverlightの記事を見つけました :ストリームからのBitmapImageが例外をスローします(壊滅的な失敗(HRESULTからの例外:0x8000FFFF(E_UNEXPECTED)))、これはたまたま同じ例外がありますが、私が読んだところ、彼はこの問題を抱えているのは彼はたくさんの画像をアップロードしていました、そしてそれは彼にとって少量の画像のためにうまくいきました。それで、私はまだこの問題を解決する方法について無知ですか?

何かアドバイスはありますか?ありがとう!

4

2 に答える 2

3

画像を再構築するバイト配列はARGB値の「生の」配列であるのに対し、Sourceプロパティは有効なPNGまたはJPGファイルを構成するバイトストリームを想定しているため、クラッシュが発生していると思います。生のARGBデータは、これらの各形式に必要な有効なヘッダーがほぼ確実に含まれていないため、有効なPNGまたはJPGファイルである可能性はほとんどありません。

クラッシュを再現できませんでした。代わりに、BitmapImageコードを実行したときに作成されていたsはPixelWidthPixelHeight両方ともゼロでした。これは、使用している画像とは異なる画像を使用していることが原因である可能性があります。いずれにせよ、クラッシュするかしないかにかかわらず、それは望ましくない動作です。

変更したデータをにロードし直す場合は、配列Imageを作成する必要はありません。オブジェクトからをbyte作成するだけです。ImageWriteableBitmap

        Image modifiedImage = new Image()
        {
            Source = writeableBitmap,
            Stretch = Stretch.None
        };

これを使用して、元の画像の下に画像のコピーを追加しました。変更された画像は、元の画像と比較して「色あせた」外観になりました。これは、すべてのアルファチャネル値を半分にした場合に予想されるものです。

バイト配列を画像に戻す必要がある場合は、FromByteArrayWriteableBitmapEx内の拡張メソッドを使用できます。Image次に、上記のようにを作成できます。

于 2012-08-13T21:20:13.140 に答える
1

私は前にこの例外に遭遇しました:

  1. サポートされていない画像タイプをSilverlightに渡す場合:BMP、...JPGとPNGのみがサポートされます。MSDNを参照してください
  2. 誤ったデータを渡す場合(すべてのストリームではない、または誤った形式)
于 2012-08-13T14:14:54.730 に答える