2016-01-12 4 views
5

Моя программа обрабатывает некоторые изображения в пакетном режиме. Мне теперь нужно прочитать указатель ориентации exif изображения, повернуть его в нужную ориентацию, сделать некоторые обработки и сохранить изображение без ориентации тегов EXIF, но с собственным вращением (или с EXIF ​​тег с правильной ориентацией)Получите EXIF-ориентированный тег, поверните на нужную ориентацию, обработайте изображение и сохраните изображение с правильной ориентацией

Я читаю EXIF ​​и Вращающийся с помощью this library:.

var bmp = new Bitmap(pathToImageFile); 
    var exif = new EXIFextractor(ref bmp, "n"); // get source from http://www.codeproject.com/KB/graphics/exifextractor.aspx?fid=207371 

    if (exif["Orientation"] != null) 
    { 
    RotateFlipType flip = OrientationToFlipType(exif["Orientation"].ToString()); 

    if (flip != RotateFlipType.RotateNoneFlipNone) // don't flip of orientation is correct 
    { 
    bmp.RotateFlip(flip); 
    bmp.Save(pathToImageFile, ImageFormat.Jpeg); 
    } 

    // Match the orientation code to the correct rotation: 

    private static RotateFlipType OrientationToFlipType(string orientation) 
    { 
    switch (int.Parse(orientation)) 
    { 
    case 1: 
    return RotateFlipType.RotateNoneFlipNone; 

    case 2: 
    return RotateFlipType.RotateNoneFlipX; 

    case 3: 
    return RotateFlipType.Rotate180FlipNone; 
    case 4: 
    return RotateFlipType.Rotate180FlipX; 
    break; 
    case 5: 
    return RotateFlipType.Rotate90FlipX; 
    break; 
    case 6: 
    return RotateFlipType.Rotate90FlipNone; 
    case 7: 
    return RotateFlipType.Rotate270FlipX; 
    case 8: 
    return RotateFlipType.Rotate270FlipNone; 
    default: 
    return 
} 
} 

Это работает. но при сохранении этого изображения все еще существует тег вращения exif, который делает изображение неправильным. Что я могу сделать, это

 var bmp = new Bitmap(OS.FileName);  
     var exif = new EXIFextractor(ref bmp, "n"); 
     exif.setTag(0x112, "1"); 
     bmp.save("strippedexifimage"); 

Но этот код при использовании в цикле замедляет мою программу примерно на 50% .а там альтернативного пути? Может быть, код, чтобы противостоять вращению изображения после применения вращения, будет ли это работать?

Update:

@Hans Passant Ваш ответ работает, но результат она производит такое же, как те, продуцируемых библиотеки. Когда я использую bitmap.save(), как библиотека, так и ваш код работают. Но когда я использую следующий код для сохранения моего изображения в зависимости от формата, выбранного пользователем. Imgformat может быть imgformat = "image/png";,imgformat = "image/jpeg"; и т. Д. Некоторые изображения по-прежнему сохраняются с неправильным тегом ориентации exif. т.е.: я вижу неправильный просмотр изображения в проводнике Windows. Когда я открываю изображение с помощью MS Paint, изображение имеет правильную ориентацию. Что я делаю неправильно? Пожалуйста помоги.

private void saveJpeg(string path, Bitmap img, long quality) 
     { 


      EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality); 


      ImageCodecInfo Codec = this.getEncoderInfo(imgformat); 
      if (Codec == null) 
       return; 

      EncoderParameters encoderParams = new EncoderParameters(1); 
      encoderParams.Param[0] = qualityParam;  
      img.Save(path + ext, Codec, encoderParams); 
     } 



private 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; 
     } 
+0

Взгляните на ImageMagick. Я думаю, что он делает все, что вы хотите. Вы можете написать код для него .. или просто использовать его как есть. :) – atlaste

ответ

5
var exif = new EXIFextractor(ref bmp, "n") 

Использование библиотеки для реализации функции может сэкономить много времени. Или вы застряли в течение нескольких дней, когда библиотека плохо разработана или сложна в использовании. ref bmp - это первое громкое предупреждение, вы упали в яму отчаяния, пытаясь указать значение в виде строки. Это было привлекательно, потому что вам не нужно было учитывать, что «тип» может означать в правильной перегрузке setTag(). Это тип 3 и требует байта [] с двумя элементами. Это невозможно обнаружить, вы можете использовать библиотеку только тогда, когда она вам не нужна.

Погрузитесь в библиотеку, это не поможет. Тег EXIF, который сохраняет ориентацию, имеет id 0x112 и кодируется как 16-битное значение. Просто используйте System.Drawing, чтобы прочитать значение и заставить его вернуться к 1. Примерно так:

static void FixImageOrientation(Image srce) { 
    const int ExifOrientationId = 0x112; 
    // Read orientation tag 
    if (!srce.PropertyIdList.Contains(ExifOrientationId)) return; 
    var prop = srce.GetPropertyItem(ExifOrientationId); 
    var orient = BitConverter.ToInt16(prop.Value, 0); 
    // Force value to 1 
    prop.Value = BitConverter.GetBytes((short)1); 
    srce.SetPropertyItem(prop); 

    // Rotate/flip image according to <orient> 
    switch (orient) { 
     // etc... 
    } 
} 
+0

Спасибо большое. Я искал, есть ли способ сделать это напрямую с помощью кода, но не смог найти никаких. Возвращаемые значения 'orient', которые находятся в моем случае коммутатора (я имею в виду 1,2,3. .etc) – techno

+0

См. обновление. – techno

+0

Можете ли вы поделиться своим мнением по поводу моего обновления сэр? – techno