C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 167 を表示中)
■96455 / )  Re[1]: ジェネリックメソッドとCS1503エラー
□投稿者/ 魔界の仮面弁士 (2923回)-(2020/11/25(Wed) 11:14:17)
2020/11/25(Wed) 13:58:50 編集(投稿者)

No96452 (紅 さん) に返信
> else if (ext.EndsWith(".png"))
EndsWith は不要なのでは?
仮に二重拡張子だったとしても、ext には 末尾の .png のみが保持されているはずですよね。


> こういった使い方はできないのでしょうか?
今回の場合、BitmapFrame.Create(bmp) として渡そうとしているわけですから、
bmp のデータ型が、以下のいずれか(あるいはその派生クラス)でないとエラーになります。
 1) System.IO.Stream クラス
 2) System.Uri クラス
 3) System.Windows.Media.Imaging.BitmapSource クラス

これらの型には互換性が無いため、ジェネリックの型制約については
where Type:class か where Type:notnull ぐらいしか付与できません。

今回の場合はジェネリックにするメリットが無さそうなので、
オーバーロードで解決させた方が良いと思いますよ。


#nullable enable
private void SaveImageFile(string path, ImageSource image)
{
  var bmp = image as BitmapSource ?? throw new ArgumentOutOfRangeException(nameof(image));
  SaveImageFile(path, bmp);

}
private void SaveImageFile(string path, BitmapSource bmp)
{

  BitmapFrame frame;
  switch (bmp)
  {
    case CroppedBitmap src: // CroppedBitmap の時に行いたい処理
      frame = BitmapFrame.Create(src);
      break;
    case BitmapSource:
    default:
      frame = BitmapFrame.Create(bmp);
      break;
  }
  string ext = System.IO.Path.GetExtension(path).ToLower();
  if (encoderFactory.TryGetValue(ext, out var factory))
  {
    using (var stream = new FileStream(path, FileMode.Create))
    {
      var encoder = factory();
      encoder.Frames.Add(frame);
      encoder.Save(stream);
    }
  }
  else
  {
    // throw new ArgumentOutOfRangeException(nameof(bmp), "対応していない拡張子です。");
    MessageBox.Show(
      "対応していない拡張子です。画像の保存に失敗しました。",
      "エラー",
      MessageBoxButton.OK,
      MessageBoxImage.Error);
  }
}
private static readonly Dictionary<string, Func<BitmapEncoder>> encoderFactory = new()
{
  [".jpeg"]= () => new JpegBitmapEncoder(),
  [".jpg"] = () => new JpegBitmapEncoder(),
  [".png"] = () => new PngBitmapEncoder(),
  [".gif"] = () => new GifBitmapEncoder(),
  [".bmp"] = () => new BmpBitmapEncoder(),
};
返信 編集キー/


管理者用

- Child Tree -