1

画像形式を別の形式に変換できるパイプライン コンポーネントを構築しています (たとえば、jpg から png など)。

using (System.Drawing.Bitmap bmpSource = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(msgReceived.BodyPart.Data))
{
    VirtualStream strConvertedImage = new VirtualStream();

    bmpSource.Save(strConvertedImage, System.Drawing.Imaging.ImageFormat.Png);

    strConvertedImage.Flush();
    strConvertedImage.Position = 0;

    ctxPipeline.ResourceTracker.AddResource(strConvertedImage);
}

msgReceived.BodyPart.Data = strConvertedImage;

ファイル アダプターを使用して受信パイプラインでこのコンポーネントを使用すると、正常に実行されますが、パススルー送信ポートとファイル アダプターを使用してサブスクライブすると、書き込まれるファイルは実際のイメージの一部にすぎません。

ノート:

Windows コンソール アプリケーションでこの同じコードを使用できます (BizTalk メッセージ ストリームではなくファイル ストリームからソース ビットマップをロードすることを除いて)。

ソースストリームと関係があると思います。

奇妙な動作に思えますが、msgReceived.BodyPart.Data の長さと位置のプロパティを調べると、長さは 904678 です。位置は 0 です。位置は 0 のままで、ビットマップを読み込んで保存しても変化しません。BitMap.FromStream メソッドがロードの完了後にストリームの先頭をシークしない限り、ビットマップをロードすると位置が変わると予想していました。

また、ビットマップを新しいストリームに png として保存すると、新しいストリームの長さは常に 54789 で、画像の最初のパーティのみを表します。同じビットマップ オブジェクトをすぐに新しいストリームに再度保存すると、サイズは 1400868 になり、イメージ全体を表し、msgReceived.BodyPart.Data.Position は 904678 になり、ソース ストリーム全体が読み取られたことを示します。

次に例を示します。

using (System.Drawing.Bitmap bmpSource = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(msgReceived.BodyPart.Data))
{
    VirtualStream strConvertedImage = new VirtualStream();
    bmpSource.Save(strConvertedImage, System.Drawing.Imaging.ImageFormat.Png);
    strConvertedImage.Flush();
    strConvertedImage.Position = 0;

    //msgReceived.BodyPart.Data.Position is 0
    //msgReceived.BodyPart.Data.Length is 904678
    //strConvertedImage.Position is 54789 (Only part of image was saved)

    strConvertedImage = new VirtualStream();
    bmpSource.Save(strConvertedImage, System.Drawing.Imaging.ImageFormat.Png);

    //msgReceived.BodyPart.Data.Position is 904678
    //msgReceived.BodyPart.Data.Length is 904678
    //strConvertedImage.Position is 1400868 (full image was saved)

    msgReceived.BodyPart.Data = strConvertedImage;
    ctxPipeline.ResourceTracker.AddResource(strConvertedImage);
}

msgReceived.BodyPart.Data の位置が 2 回目の保存でしか進まないのはなぜですか? また、最初の保存試行で変換された画像の一部しか保存されないのはなぜですか。私は困惑しています!

4

1 に答える 1

1

Data最後にストリームを設定する場合を除いて、プロパティの使用は避けたいと思います。MSDNによると、データ ストリームのクローンが作成され、予期しない動作が発生することがあります (ストリームが正常に返されたDataにもかかわらず、一部のアダプターでプロパティが null になっているのを見たことがあります)。代わりにGetOriginalDataStream()使用してください。GetOriginalDataStream()また、パイプラインでブロックを使用することも避けたいと思いusingます。あなたの例が問題になる理由はわかりませんが、元のデータ ストリームを破棄してしまうストリームを誤って破棄するのは非常に簡単です。

例えば、

Stream originalStream = msgReceived.BodyPart.GetOriginalDataStream();
originalStream.Seek(0, SeekOrigin.Begin);
VirtualStream vtsConvertedImage = new VirtualStream()
System.Drawing.Bitmap bmpSource = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(originalStream);

bmpSource.Save(vtsConvertedImage, System.Drawing.Imaging.ImageFormat.Png);

vtsConvertedImage.Flush();
vts.ConvertedImage.Seek(0, SeekOrigin.Begin);

msgReceived.BodyPart.Data = vtsConvertedImage;
ctxPipeline.ResourceTracker.AddResource(vtsConvertedImage);
ctxPipeline.ResourceTracker.AddResource(bmpSource);
于 2015-05-15T15:12:59.433 に答える