4

画像を読み込んでサイズを変更し、新しい背景に配置するルーチンがあります(新しいビットマップ、サイズが設定されているだけです)。

これはすべて完全に機能しますが、出力するPNGファイルのサイズを縮小したいと思います.JPEGファイルを出力すると、期待するファイルサイズが約4Kになりますが、PNGファイルのサイズは30Kを超えます.

PNG では JPEG レベルに到達できないことはわかっていますが、もう少しうまくやれると思います。

出力された PNG をFireworksにロードすると、背景とサイズ変更された画像がまだ別々のレイヤーであることに注意してください。Fireworks で PNG をフラット化すると、ファイルサイズが 5 ~ 10K ほど小さくなります。

まず、出力時に PNG をプログラムで平坦化する方法はありますか?

第二に、PNG サイズを縮小するために推奨できるものは他にありますか?

背景を透明のままにしたいので、PNGファイルを使用しています。

コード:

private static void ResizeImage(String ImageInPath, int MaxWidth, int MaxHeight, String ImageOutPath, Boolean PadImage, Color MyColour)
{
    Bitmap MyImage = new Bitmap(ImageInPath);
    Bitmap MyResizedImage = null;

    int XPosition = 0;
    int YPosition = 0;
    float Ratio = MyImage.Width / (float)MyImage.Height;

    int MyImageHeight = MyImage.Height;
    int MyImageWidth = MyImage.Width;

    if (MyImage.Width > MyImage.Height)
    {
        if (MyImage.Width > MaxWidth)
            MyResizedImage = new Bitmap(MyImage, new Size(MaxWidth, (int)Math.Round(MaxWidth /
            Ratio, 0)));
        YPosition = (MaxHeight / 2) - (MyResizedImage.Height / 2);
    }
    else if (MyImage.Height > MyImage.Width)
    {
        if (MyImage.Height > MaxHeight)
            MyResizedImage = new Bitmap(MyImage, new Size((int)Math.Round(MaxWidth * Ratio,
            0), MaxHeight));
        XPosition = (MaxWidth / 2) - (MyResizedImage.Width / 2);
    }


    if (PadImage)
    {
        Bitmap MyUnderlay = new Bitmap(MaxWidth, MaxHeight);
        var Canvas = Graphics.FromImage(MyUnderlay);
        Canvas.Clear(MyColour);
        Canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
        Canvas.DrawImage(MyResizedImage, XPosition, YPosition);
        Canvas.Save();
        if (MyColour == Color.Transparent)
        {
            MyUnderlay.Save(ImageOutPath + ".png", ImageFormat.Png);
        }
        else
        {
            MyUnderlay.Save(ImageOutPath, ImageFormat.Jpeg);
        }

        Canvas.Dispose();
        MyUnderlay.Dispose();
    }
    else
    {
        MyResizedImage.Save(ImageOutPath, ImageFormat.Jpeg);
    }

    MyResizedImage.Dispose();
    MyImage.Dispose();
}
4

1 に答える 1

8

スーパーユーザーの回答、How to read Fireworks PNGmultilayer files without Fireworksでは、Fireworks には複数のレイヤーを PNG ファイルに保存するための PNG 拡張子があると説明されています。平坦化により、余分なレイヤーが削除されます。そもそもファイルが Fireworks で作成されたものではないことを考えると、理論的には「フラット化」してもファイルに影響はありません。サイズの縮小は、Firework が PNG ファイルを最適化して保存したためだと思われます。

PNG の最適化に使用するツールは次のとおりです。

  1. PNG8に変換: 色が少ない場合 (スクリーンショットなど)、pngnqまたはGIMP のインデックス付きカラー モードを使用して 256 色まで量子化します。PNG8 は、PNG24 または PNG32 より小さくすることができます。詳細については、PNG8 – The Clear Winnerを参照してください。
  2. Optipng、高速な汎用 PNG オプティマイザー。C# PNG 最適化チュートリアルには、C# からoptipngを実行する方法の詳細が記載されています。
  3. 最後に、pngoutは低速で​​すが、多くの場合 (80 ~ 90% の時間)、optipng よりも PNG を圧縮することができます。ただし、optipng は pngout が試行しない他の最適化を自動的に行うため、最初に optipng を実行します。

PNG ファイルの最適化に関心がある場合、PNG の仕様は驚くほど単純なので、Smallest possible transparent PNGを参照してください。仕様と同様に、実装も驚くほど単純です。たとえば、単一ファイルの純粋なPython実装png.py (pypng)を考えてみましょう。

于 2010-01-15T22:24:16.520 に答える