Exif情報を見て回転・反転すると補正できる
void RotateExif(Image* pImage) { //PropertyTagOrientation int n = pImage->GetPropertyItemSize(PropertyTagOrientation); if (n > 0) { Gdiplus::PropertyItem* pItem = (Gdiplus::PropertyItem*)malloc(n); if (pImage->GetPropertyItem(PropertyTagOrientation, n, pItem) == Ok) { if (pItem->type == PropertyTagTypeShort) { int nOrientation = *(short*)pItem->value; TRACE("RotateExif Orientation=%d\n", nOrientation); /* 行と列の観点から見た、画像の方向。 Tag = 274 (112.H) Type = SHORT Count = 1 Default = 1 1 = 0 番目の行が目で見たときの画像の上(visual top)、0 番目の列が左側(visual left-hand side)となる。 2 = 0 番目の行が目で見たときの画像の上、0 番目の列が右側(visual right-hand side)となる。 3 = 0 番目の行が目で見たときの画像の下(visual bottom)、0 番目の列が右側となる。 4 = 0 番目の行が目で見たときの画像の下、0 番目の列が左側となる。 5 = 0 番目の行が目で見たときの画像の左側、0 番目の列が上となる。 6 = 0 番目の行が目で見たときの画像の右側、0 番目の列が上となる。 7 = 0 番目の行が目で見たときの画像の右側、0 番目の列が下となる。 8 = 0 番目の行が目で見たときの画像の左側、0 番目の列が下となる。 その他 = 予約 */ RotateFlipType type = RotateNoneFlipNone; switch (nOrientation) { case 1: // 上 // 左 右 // 下 // そのまま break; case 2: // 上 // 右 左 // 下 // 左右反転 type = RotateNoneFlipX; break; case 3: // 下 // 右 左 // 上 // 上下左右反転 type = RotateNoneFlipXY; break; case 4: // 下 // 左 右 // 上 // 上下反転 type = RotateNoneFlipY; break; case 5: // 左 // 上 下 // 右 // 90度回転後左右反転 type = Rotate90FlipX; break; case 6: // 右 // 上 下 // 左 // 90度回転 type = Rotate90FlipNone; break; case 7: // 右 // 下 上 // 左 // 270度回転後左右反転 type = Rotate270FlipX; break; case 8: // 左 // 下 上 // 右 // 270度回転 type = Rotate270FlipNone; break; } if (type != RotateNoneFlipNone) pImage->RotateFlip(type); } } free(pItem); } }
開始点だけを指定するDrawImageはつい等倍と思ってしまうが実はDPI値で勝手に拡大縮小されるのでサイズを指定するDrawImageを使うべし
×g.DrawImage(&bm, x, y);
○g.DrawImage(&bm, x, y, bm.GetWidth(), bm.GetHeight());