3

計画

ある程度の品質を保ちながら、画像サイズを小さくする必要があります。ただし、GIF、JPEG、JPG、PNGは受け付けています。


現状

画像のアップロードは完全に機能しており、画像の幅や高さを調整することができました。

Stackoverflowで素晴らしい投稿を見つけました。これは、非常に優れたコードのサンプルを提供してくれました。

Image myImage = //... load the image somehow 

// 50%の品質で画像を保存しますSaveJpeg(destImagePath、myImage、50); //これを追加!System.Drawing.Imagingを使用します。

                      /// <summary> 
    /// Saves an image as a jpeg image, with the given quality 
    /// </summary> 
    /// <param name="path">Path to which the image would be saved.</param> 
    // <param name="quality">An integer from 0 to 100, with 100 being the 
    /// highest quality</param> 
    public static void SaveJpeg (string path, Image img, int quality) 
    { 
        if (quality<0  ||  quality>100) 
            throw new ArgumentOutOfRangeException("quality must be between 0 and 100."); 


        // Encoder parameter for image quality 
        EncoderParameter qualityParam = 
            new EncoderParameter (Encoder.Quality, quality); 
        // Jpeg image codec 
        ImageCodecInfo   jpegCodec = GetEncoderInfo("image/jpeg"); 

        EncoderParameters encoderParams = new EncoderParameters(1); 
        encoderParams.Param[0] = qualityParam; 

        img.Save (path, jpegCodec, encoderParams); 
    } 

    /// <summary> 
    /// Returns the image codec with the given mime type 
    /// </summary> 
    private static ImageCodecInfo GetEncoderInfo(string mimeType) 
    { 
        // Get image codecs for all image formats 
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); 

        // Find the correct image codec 
        for(int i=0; i<codecs.Length; i++) 
            if(codecs[i].MimeType == mimeType) 
                return codecs[i]; 
        return null; 
    } 

ただし、このコードはJPEG画像でのみ機能するようです。


質問

  1. JPEG形式はPNGやGIFよりも軽いですか?もしそうなら、すべての画像をJPEGに変換して保存する必要がありますか?
    • この場合、サンプルコードは問題なく機能するはずです。
    • そうでない場合、サンプルコードを考えると、他の形式を使用するにはどうすればよいですか?
  2. 画像の重みを減らすためにC#で使用できるツールは何ですか?(寸法を小さくする以外に)
  3. 読みやすさ、色、鮮明さ、鮮明さの合理的な状態を維持するために、画像に推奨される「品質の低下」は何ですか?
  4. サーバーでの画像処理は「重い」ですか?
4

4 に答える 4

3

First of all, JPEG uses a "lossy" compression algorithm, which is why you can tune the quality. Lower quality will result better compression at the cost of higher data loss. Also realize that the JPEG format is designed for photograph-like images, and applying JPEG to other types of images can be disappointing (google "jpeg artifacts").

PNG and GIF are lossless, so they can't support a quality parameter. This isn't to say that you can't get better compression out of them - there's a variety of tools to reduce the size of your PNG's (pngcrush, punypng, etc), but these tools (mostly) work in a fundamentally different way than JPEG compressors do. One thing to note is that GIF supports a smaller palette than PNG - only up to 256 colors.

So to answer your questions in order:

  1. Can't really compare, since compression in JPEG comes with a tradeoff while compression in PNG and GIF doesn't, and how tolerable the tradeoff is depends on the type of image. That is, JPEG will often give better compression, but if the image isn't a photograph the result will be noticeably worse.

  2. Your code for JPEG is fine. Google for C#-compatible tools for PNG.

  3. You'll need to experiment with the types of images you expect.

  4. Yes.

于 2012-09-13T23:50:55.937 に答える
0

私の記事20画像サイズ変更の落とし穴を読みたいと思うかもしれません。それはあなたの4つの質問のうちの3つをカバーしています。

于 2012-09-24T05:44:11.043 に答える
0

これはさまざまな方法で行うことができます。

最良の方法の1つは、すべての画像をjpegに変換することです。これは、サイズを小さくすると鮮明さが向上するためです。この場合、特定の画像の高さや幅を変更する必要はありません。

方法1:すべての画像をjpegに変換します(追加の圧縮は必要ありません)

  private static void VaryQualityLevel(Image imgToResize,string imageName)
      {
        // Get a bitmap.
        Bitmap bmp1 = new Bitmap(imgToResize);
        ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);

        // Create an Encoder object based on the GUID
        // for the Quality parameter category.
        System.Drawing.Imaging.Encoder myEncoder =
            System.Drawing.Imaging.Encoder.Quality;

        // Create an EncoderParameters object.
        // An EncoderParameters object has an array of EncoderParameter
        // objects. In this case, there is only one
        // EncoderParameter object in the array.
        EncoderParameters myEncoderParameters = new EncoderParameters(1);

        EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder,
            50L);
        myEncoderParameters.Param[0] = myEncoderParameter;

        var fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Download/"), imageName+".jpeg");
        bmp1.Save(fileSavePath, jgpEncoder,
            myEncoderParameters);

        //myEncoderParameter = new EncoderParameter(myEncoder, 100L);
        //myEncoderParameters.Param[0] = myEncoderParameter;
        //fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Download/"), "TestPhotoQuality100.jpeg");
        //bmp1.Save(fileSavePath, jgpEncoder,
        //    myEncoderParameters);

        // Save the bitmap as a JPG file with 75 quality level compression.
        myEncoderParameter = new EncoderParameter(myEncoder, 75L);
        //myEncoderParameters.Param[0] = myEncoderParameter;
        //fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Download/"), "TestPhotoQuality75.jpeg");
        //bmp1.Save(fileSavePath, jgpEncoder,
        //    myEncoderParameters);

    }

    private static ImageCodecInfo GetEncoder(ImageFormat format)
    {

        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

        foreach (ImageCodecInfo codec in codecs)
        {
            if (codec.FormatID == format.Guid)
            {
                return codec;
            }
        }
        return null;
        }

方法2:画像の高さと幅を変更する(jpeg変換なし)

CommonConstant.CS

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EmptyDemo.compression
{
#region[Directive]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
#endregion[Directive]

/// <summary>
/// This class is used to get the constants
/// </summary>
public class CommonConstant
{
    public const string JPEG = ".jpeg";
    public const string PNG = ".png";
    public const string JPG = ".jpg";
    public const string BTM = ".btm";
}
}

ImageCompress.CS

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EmptyDemo.compression
{
#region[Directive]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
#endregion[Directive]

/// <summary>
/// This class is used to compress the image to
/// provided size
/// </summary>
public class ImageCompress
{
    #region[PrivateData]
    private static volatile ImageCompress imageCompress;
    private Bitmap bitmap;
    private int width;
    private int height;
    private Image img;
    #endregion[Privatedata]

    #region[Constructor]
    /// <summary>
    /// It is used to restrict to create the instance of the      ImageCompress
    /// </summary>
    private ImageCompress()
    {
    }
    #endregion[Constructor]

    #region[Poperties]
    /// <summary>
    /// Gets ImageCompress object
    /// </summary>
    public static ImageCompress GetImageCompressObject
    {
        get
        {
            if (imageCompress == null)
            {
                imageCompress = new ImageCompress();
            }
            return imageCompress;
        }
    }

    /// <summary>
    /// Gets or sets Width
    /// </summary>
    public int Height
    {
        get { return height; }
        set { height = value; }
    }

    /// <summary>
    /// Gets or sets Width
    /// </summary>
    public int Width
    {
        get { return width; }
        set { width = value; }
    }

    /// <summary>
    /// Gets or sets Image
    /// </summary>
    public Bitmap GetImage
    {
        get { return bitmap; }
        set { bitmap = value; }
    }
    #endregion[Poperties]

    #region[PublicFunction]
    /// <summary>
    /// This function is used to save the image
    /// </summary>
    /// <param name="fileName"></param>
    /// <param name="path"></param>
    public void Save(string fileName, string path)
    {
        if (ISValidFileType(fileName))
        {
            string pathaname = path + @"\" + fileName;
            save(pathaname, 60);
        }
    }
    #endregion[PublicFunction]

    #region[PrivateData]
    /// <summary>
    /// This function is use to compress the image to
    /// predefine size
    /// </summary>
    /// <returns>return bitmap in compress size</returns>
    private Image CompressImage()
    {
        if (GetImage != null)
        {
            Width = (Width == 0) ? GetImage.Width : Width;
            Height = (Height == 0) ? GetImage.Height : Height;
            Bitmap newBitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
            newBitmap = bitmap;
            newBitmap.SetResolution(80, 80);
            return newBitmap.GetThumbnailImage(Width, Height, null, IntPtr.Zero);
        }
        else
        {
            throw new Exception("Please provide bitmap");
        }
    }

    /// <summary>
    /// This function is used to check the file Type
    /// </summary>
    /// <param name="fileName">String data type:contain the file name</param>
    /// <returns>true or false on the file extention</returns>
    private bool ISValidFileType(string fileName)
    {
        bool isValidExt = false;
        string fileExt = Path.GetExtension(fileName);
        switch (fileExt.ToLower())
        {
            case CommonConstant.JPEG:
            case CommonConstant.BTM:
            case CommonConstant.JPG:
            case CommonConstant.PNG:
                isValidExt = true;
                break;
        }
        return isValidExt;
    }

    /// <summary>
    /// This function is used to get the imageCode info
    /// on the basis of mimeType
    /// </summary>
    /// <param name="mimeType">string data type</param>
    /// <returns>ImageCodecInfo data type</returns>
    private ImageCodecInfo GetImageCoeInfo(string mimeType)
    {
        ImageCodecInfo[] codes = ImageCodecInfo.GetImageEncoders();
        for (int i = 0; i < codes.Length; i++)
        {
            if (codes[i].MimeType == mimeType)
            {
                return codes[i];
            }
        }
        return null;
    }
    /// <summary>
    /// this function is used to save the image into a
    /// given path
    /// </summary>
    /// <param name="path">string data type</param>
    /// <param name="quality">int data type</param>
    private void save(string path, int quality)
    {
        img = CompressImage();
        ////Setting the quality of the picture
        EncoderParameter qualityParam =
            new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
        ////Seting the format to save
        ImageCodecInfo imageCodec = GetImageCoeInfo("image/jpeg");
        ////Used to contain the poarameters of the quality
        EncoderParameters parameters = new EncoderParameters(1);
        parameters.Param[0] = qualityParam;
        ////Used to save the image to a  given path
        img.Save(path, imageCodec, parameters);
    }
    #endregion[PrivateData]
}
}

ここでは、jqueryとWebサービスを使用して画像をアップロードし、ファイルをformdataとして渡します。

    [WebMethod]
    public void UploadFile()
     {
         if (HttpContext.Current.Request.Files.AllKeys.Any())
         {
             // Get the uploaded image from the Files collection
             var httpPostedFile = HttpContext.Current.Request.Files["UploadedImage"];
             if (httpPostedFile != null)
             {
                 ImageCompress imgCompress = ImageCompress.GetImageCompressObject;
                 imgCompress.GetImage = new System.Drawing.Bitmap(httpPostedFile.InputStream);
                 imgCompress.Height = 260;
                 imgCompress.Width = 358;
                 //imgCompress.Save(httpPostedFile.FileName, @"C:\Documents and Settings\Rasmi\My Documents\Visual Studio2008\WebSites\compressImageFile\Logo");
                 imgCompress.Save(httpPostedFile.FileName, HttpContext.Current.Server.MapPath("~/Download/"));

             }
         }
     }
于 2016-10-12T09:44:58.857 に答える
0

同じコンセプトを使用して、スケーリング係数を変更するだけで品質を損なうことなく画像のサイズを変更しています。画像をアップロードした後のソーシャルネットワーキングサイトでは、写真のサイズが小さくなりますが、この投稿を書き込もうとした後、品質は同じになります

using System.Drawing.Imaging;
using System.Drawing;

public partial class Default3 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        VaryQualityLevel();
    }
    private void VaryQualityLevel()
    {
        Bitmap bmp1 = new Bitmap(Server.MapPath("test2.png"));
        ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
        System.Drawing.Imaging.Encoder myEncoder =System.Drawing.Imaging.Encoder.Quality;
        EncoderParameters myEncoderParameters = new EncoderParameters(1);
        EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L);
        myEncoderParameters.Param[0] = myEncoderParameter;
        bmp1.Save(Server.MapPath("~/Images/1.jpg"), jgpEncoder, myEncoderParameters);
        //myEncoderParameter = new EncoderParameter(myEncoder, 75L);
        //myEncoderParameters.Param[0] = myEncoderParameter;
        //bmp1.Save(Server.MapPath("~/Images/2.jpg"), jgpEncoder, myEncoderParameters);

    }
    private ImageCodecInfo GetEncoder(ImageFormat format)
    {
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

        foreach (ImageCodecInfo codec in codecs)
        {
            if (codec.FormatID == format.Guid)
            {
                return codec;
            }
        }
        return null;
    }
}
于 2018-01-31T09:01:11.260 に答える