C # Вращающийся JPG без потери качества - PullRequest
2 голосов
/ 29 февраля 2012

Итак, я читаю файлы из каталога, выясняя, в каком направлении их нужно вращать.Вращающийся, а затем сохранение.Эта часть работает ... Проблема в том, что после сохранения файла он снова сжимается, и я перехожу с 1,5-миллиметровых изображений на 250-тысячные.Мне нужно сохранить размер файла вокруг оригинала.Я пытался использовать jhead.exe и вызывать его из командной строки, но не смог передать ни один из моих аргументов.Вот мой фрагмент кода для обнаружения, поворота и сохранения.

foreach (FileInfo f in dir.GetFiles("*.jpg"))
{
    try
    {
        string ExportName = "";

        Bitmap originalImage = new Bitmap(f.FullName.ToString());

        Info inf = new Info(originalImage);

        gma.Drawing.ImageInfo.Orientation orientation = gma.Drawing.ImageInfo.Orientation.TopLeft;
        try
        {
            orientation = inf.Orientation;
        }
        catch
        {
            orientation = gma.Drawing.ImageInfo.Orientation.TopLeft;
        }

        originalImage = CheckRotation(originalImage, orientation);

        progressBar.Value = progressBar.Value + 1;
        originalImage.Save(f.FullName.ToString(), ImageFormat.Jpeg);
        Application.DoEvents();


    }

private Bitmap CheckRotation(Bitmap inputImage, gma.Drawing.ImageInfo.Orientation orientation)
{

    Bitmap rotatedImage = inputImage;

    switch (orientation)
    {
        case gma.Drawing.ImageInfo.Orientation.LeftBottom:
            rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipXY);
            break;
        case gma.Drawing.ImageInfo.Orientation.RightTop:
            rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
            break;
        default:
            break;
    }
    return rotatedImage;
}

Ответы [ 3 ]

2 голосов
/ 01 марта 2012
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); 
ImageCodecInfo ici = null; 

foreach (ImageCodecInfo codec in codecs)
{ 
    if (codec.MimeType == "image/jpeg") 
    ici = codec; 
} 

EncoderParameters ep = new EncoderParameters(); 
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100);

originalImage.Save(f.FullName.ToString(), ici, ep);

Это будет использовать 100% качество - но будьте осторожны, JPEG все еще сжимает с потерями - попробуйте использовать png, если вам нужно качество без потерь.

1 голос
/ 13 февраля 2016

Ключом для редактирования JPEG без потерь является использование всегда одного и того же QualityLevel и BitmapCreateOptions.PreservePixelFormat |BitmapCreateOptions.IgnoreColorProfile с BitmapCacheOption.None.

И помните, что даже если вы используете QualityLevel 100, качество будет ухудшаться.Этот метод отключается только в первый раз, потому что он переходит от неизвестного QualityLevel к 80, но любое другое редактирование jpeg без потерь.

RotateJpeg(@"d:\!test\TestInTest\20160209_143609.jpg", 80, Rotation.Rotate90);

public bool RotateJpeg(string filePath, int quality, Rotation rotation) {
  var original = new FileInfo(filePath);
  if (!original.Exists) return false;
  var temp = new FileInfo(original.FullName.Replace(".", "_temp."));

  const BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;

  try {
    using (Stream originalFileStream = File.Open(original.FullName, FileMode.Open, FileAccess.Read)) {
      JpegBitmapEncoder encoder = new JpegBitmapEncoder {QualityLevel = quality, Rotation = rotation};

      //BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile and BitmapCacheOption.None
      //is a KEY to lossless jpeg edit if the QualityLevel is the same
      encoder.Frames.Add(BitmapFrame.Create(originalFileStream, createOptions, BitmapCacheOption.None));

      using (Stream newFileStream = File.Open(temp.FullName, FileMode.Create, FileAccess.ReadWrite)) {
        encoder.Save(newFileStream);
      }
    }
  }
  catch (Exception) {
    return false;
  }

  try {
    temp.CreationTime = original.CreationTime;
    original.Delete();
    temp.MoveTo(original.FullName);
  }
  catch (Exception) {
    return false;
  }

  return true;
}
0 голосов
/ 07 февраля 2017

Легко ...

public static void Rotate90(string fileName)
{ 
    Image Pic; 
    string FileNameTemp; 
    Encoder Enc = Encoder.Transformation; 
    EncoderParameters EncParms = new EncoderParameters(1); 
    EncoderParameter EncParm; 
    ImageCodecInfo CodecInfo = GetEncoderInfo("image/jpeg"); 

    // load the image to change 
    Pic = Image.FromFile(fileName); 

    // we cannot store in the same image, so use a temporary image instead 
    FileNameTemp = fileName + ".temp"; 

    // for rewriting without recompression we must rotate the image 90 degrees
    EncParm = new EncoderParameter(Enc,(long)EncoderValue.TransformRotate90); 
    EncParms.Param[0] = EncParm; 

    // now write the rotated image with new description 
    Pic.Save(FileNameTemp,CodecInfo,EncParms); 
    Pic.Dispose(); 
    Pic = null; 

    // delete the original file, will be replaced later 
    System.IO.File.Delete(fileName); 
    System.IO.File.Move(FileNameTemp, fileName); 
}
...