1月15日にリリースしたミコソフトスライドショーX2.0で画像が正しく表示されない不具合が報告されました。


直ぐに公開を中止して原因を調査したところ、動的テクスチャの1ライン毎のバイト数の設定に誤りがあるためであることが判明しました。


つまり、テクスチャ画像データの1ライン毎のバイト数は、必ずしも2の階乗にはならないということです。


では、1ライン毎のバイト数をどうやって取得するかですが、


LockRectangle メソッドを使う際に、pitch 引数を指定すれば、


pitch へ1ライン毎のバイト数が設定されますので、この値を使用すればOKです。


以下に、「動的テクスチャ その3」で紹介したサンプルを修正したコードを掲載します。


======================== ここから ========================

// 画像ジャグ配列データ作成
public static byte[][] CreateBitmapBytes(Bitmap bmp)
{
  byte[][] bmpBytes = new byte[0][];
  BitmapData bmpData = null;
  try
  {
    bmpData = bmp.LockBits(
      new Rectangle(0, 0, bmp.Width, bmp.Height),
      ImageLockMode.ReadOnly,
      bmp.PixelFormat);

    IntPtr ptr = bmpData.Scan0;
    bmpBytes = new byte[bmpData.Height][];
    for (int i = 0; i < bmpData.Height; i++)
    {
      bmpBytes[i] = new byte[bmpData.Stride];
      System.Runtime.InteropServices.Marshal.Copy(
        (IntPtr)(ptr.ToInt64() + bmpData.Stride * i),
        bmpBytes[i], 0, bmpData.Stride);
    }
  }
  catch (Exception)
  {
    bmpBytes = new byte[0][];
  }
  finally
  {
    if (bmpData != null)
      bmp.UnlockBits(bmpData);
  }
  return bmpBytes;
}

// 動的テクスチャ更新
public static void UpdateTexture(
  Texture tex, byte[][] bmpBytes, Size size)
{
  if (tex != null && bmpBytes.Length > 0)
  {
    int textureStride = 0;
    using (GraphicsStream gs = tex.LockRectangle(
      0, LockFlags.Discard, out textureStride))
    {
      if (gs.CanWrite)
        try
        {
          int stride = bmpBytes[0].Length;
          for (int i = 0; i < bmpBytes.Length; i++)
          {
            int offset = i * textureStride;
            gs.Seek(
              offset,
              System.IO.SeekOrigin.Begin);
            gs.Write(bmpBytes[i], 0, stride);
          }
        }
        catch (Exception) { }
      tex.UnlockRectangle(0);
      gs.Close();
    }
  }
}

======================== ここまで ========================