2012-07-17 2 views
1

입력 스트림 (이미지 압축 파일)을 가져 와서 각 파일을 추출하려고합니다. 하지만 저장하기 전에 각 이미지의 품질을 낮춰야합니다 (품질이 < 인 경우 100). 다음을 시도했지만 이미지를 압축하지 않습니다.저장하기 전에 이미지/스트림 품질 줄이기

public void UnZip(Stream inputStream, string destinationPath, int quality = 80) { 
    using (var zipStream = new ZipInputStream(inputStream)) { 
     ZipEntry entry; 

     while ((entry = zipStream.GetNextEntry()) != null) { 
      var directoryPath = Path.GetDirectoryName(destinationPath + Path.DirectorySeparatorChar + entry.Name); 
      var fullPath = directoryPath + Path.DirectorySeparatorChar + Path.GetFileName(entry.Name); 

      // Create the stream to unzip the file to 
      using (var stream = new MemoryStream()) { 
       // Write the zip stream to the stream 
       if (entry.Size != 0) { 
        var size = 2048; 
        var data = new byte[2048]; 

        while (true) { 
         size = zipStream.Read(data, 0, data.Length); 

         if (size > 0) 
          stream.Write(data, 0, size); 
         else 
          break; 
        } 
       } 

       // Compress the image and save it to the stream 
       if (quality < 100) 
        using (var image = Image.FromStream(stream)) { 
         var info = ImageCodecInfo.GetImageEncoders(); 
         var @params = new EncoderParameters(1); 
         @params.Param[0] = new EncoderParameter(Encoder.Quality, quality); 
         image.Save(stream, info[1], @params); 
        } 
       } 

       // Save the stream to disk 
       using (var fs = new FileStream(fullPath, FileMode.Create)) { 
        stream.WriteTo(fs); 
       } 
      } 
     } 
    } 
} 

누군가 내가 잘못하고있는 것을 보여줄 수 있으면 감사하겠습니다. 또한 코드 정리에 대한 조언은보기 흉하게 성장했습니다. 감사합니다

+0

당신과 당신의 코드는 모순됩니다. "압축 해제"는 압축 해제를 의미하며 압축하는 이유에 대한 질문입니다. 당신의 질문에 더 분명하게 될 수 있습니까? –

+0

Peter 안녕하세요, 저는 zip 파일의 압축을 풀고 결과 파일을 개별적으로 압축해야했습니다. 이렇게하면 디스크 공간을 절약 할 수 있습니다. 나는 스콧의 대답이 도움이 될 것이라고 생각한다. – nfplee

답변

2

압축 된 이미지를 저장하기 위해 실제로 같은 스트림을 사용해서는 안됩니다. MSDN 설명서에는 "이미지를 만드는 데 사용 된 것과 동일한 스트림에 이미지를 저장하지 마십시오. 이렇게하면 스트림이 손상 될 수 있습니다." (MSDN Article on Image.Save(...))

또한 인코딩 할 파일 형식은 무엇입니까? 당신은 지정하지 않았습니다. 두 번째 엔코더를 찾았습니다. 결과의 순서에 의존해서는 안됩니다. 대신 특정 코덱 검색 :

var encoder = ImageCodecInfo.GetImageEncoders().Where(x => x.FormatID == ImageFormat.Jpeg.Guid).SingleOrDefault() 

... 그리고 인코더 시스템에 존재하지 않는 경우 확인하는 것을 잊지 마세요 :

if (encoder != null) 
{ .. } 

품질 매개 변수가없는 의미 모든 파일 형식. 나는 당신이 JPEG로 작업 할 수도 있다고 생각하니? 또한 100 % JPEG 품질! = 무손실 이미지를 명심하십시오. 여전히 Quality = 100으로 인코딩하고 공간을 줄일 수 있습니다.

+0

감사합니다. 인코딩에 대한 추가 조언을 주셔서 감사합니다. – nfplee

1

압축 스트림에서 이미지를 압축 해제 한 후 코드를 압축하는 코드는 없습니다. 압축 해제 된 데이터를 MemoryStream으로 가져온 다음 품질 정보 (코덱에 따라 이미지를 압축 할 수도 있고 압축하지 않을 수도 있음)를 기반으로 이미지를 동일한 스트림에 기록합니다. 먼저 읽는 스트림에 쓰지 않는 것이 좋습니다. 또한 Encoder.Quality 속성에서 나오는 "압축"은 이미지의 유형에 따라 달라지며 세부 정보는 제공하지 않습니다. 이미지 유형이 압축을 지원하고 시작 이미지 품질이 100보다 낮 으면 크기가 줄어들지 않습니다. 또한 관련 정보를 제공하지 않았습니다. 짧게 말하면, 누구에게나 진정한 답을 줄 수있는 충분한 정보를 제공하지 못했습니다.

+0

그들은 일반적으로 JPEG 인코더 인 시스템에서 발견 된 두 번째 인코더를 반환하는 'info [1]'에 의해 대상 파일 형식을 지정합니다. – Scott

+0

나는 그것에 의존하지 않는 것이 좋습니다. 그리고 원래의 이미지 스트림이 이미 JPEG보다 품질이 낮은 (기본값 80) JPEG로 제공 되었다면 JPEG는 이미 압축 된 것보다 더 압축 할 수 없으므로 아무 것도 압축하지 않는 모양을 나타냅니다 –

+0

나는 ' 그 중 하나에 의존하는 것이 좋습니다. 네 말이 맞아. 비슷한 또는 낮은 화질 설정으로 이미 JPEG로 인코딩 된 이미지 일 수도 있습니다. – Scott

관련 문제