3

以下のコードを使用して、元のファイルをロックせずにビットマップ イメージを複製しました。しかし、複製された画像 (.Gif) が元の画像と同じではないという問題に直面しています。特に、複製された画像の色が適切ではありません。

私は何か間違ったことをしていますか?イメージをメモリに保存し、元のファイルをハードディスクから削除するより良い方法はありますか?

コード:

private Bitmap CloneImage(Bitmap src)
    {
        if (src == null)
            return src;
        Bitmap bitmap = new Bitmap(src.Size.Width, src.Size.Height, src.PixelFormat);
        System.Drawing.Rectangle bounds = new System.Drawing.Rectangle(0, 0, src.Width, src.Height);
        System.Drawing.Imaging.BitmapData bmpData = src.LockBits(bounds, System.Drawing.Imaging.ImageLockMode.ReadWrite, src.PixelFormat);
        System.Drawing.Imaging.BitmapData newBmpData = bitmap.LockBits(bounds, System.Drawing.Imaging.ImageLockMode.ReadWrite, src.PixelFormat);
        IntPtr bPtr = bmpData.Scan0;
        IntPtr nbPtr = newBmpData.Scan0;
        int bytes = Math.Abs(bmpData.Stride) * src.Height;
        byte[] rgbValues = new byte[bytes];

        System.Runtime.InteropServices.Marshal.Copy(bPtr, rgbValues, 0, bytes);
        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, nbPtr, bytes);
        bitmap.UnlockBits(newBmpData);
        src.UnlockBits(bmpData);
        return bitmap;
    }

元の画像:

元の画像

複製されたイメージ:

複製イメージ

4

3 に答える 3

3

これはパレットの問題のようです。個々のピクセルは正しい位置にあるので、memcpy コードはおそらく正しいでしょう。

パレットもコピーするか、24 ビットまたは 32 ビットのピクセル形式を使用Graphics.FromImageして、ソース イメージをターゲット ビットマップにブリットします。次に、おそらくとにかく小さいファイルになるPNGとして保存できます。

于 2013-10-07T11:54:36.507 に答える
1

画像を MemoryStream に保存することで、画像のクローンを作成する方が簡単です (コードが少なくて済みます)。次に、それを MemoryStream からロードすると、複製されたビットマップが作成され、ピクセル形式をいじる必要がなくなります。

于 2013-10-07T11:54:59.720 に答える
0

この SO answerによると、ここで行っていることは、次のように難しいはずです。

private Bitmap CloneImage(Bitmap src)
{
  return new Bitmap(src);
}
于 2017-03-13T04:47:16.997 に答える