2010-04-28 1 views
1

.resx 파일을 사용하여 이미지를 내 어셈블리에 임베드하고 있습니다. 런타임에 원본 이미지를 복원하여 독립형 파일에 이미지를 저장해야합니다. System.Drawing.Bitmap 인스턴스에서 원본 파일 스트림을 추출하려면 어떻게해야합니까? 나는 Bitmap.Save()을 사용하여 스트림을 만들 수 있지만 PNG로 다시 PNG로 저장하는 경우에도 이미지를 트랜스 코딩 (그리고 실제로 - 팽창)합니다.System.Drawing.Bitmap 개체에서 원본 이미지 스트림을 추출하려면 어떻게해야합니까?

아니면 실수로 Resource에서 Bitmap으로 읽는 중입니까?

답변

2

예,이 파일을 Bitmap 개체로 읽은 후에는 원래 파일 스트림을 다시 가져올 수 없습니다. Bitmap 개체는 원래 데이터가 아닌 압축되지 않은 데이터 만 포함합니다.

리소스를 바이트 데이터로 읽어야합니다. 당신은 자원 스트림에서 읽고 파일에 쓸 수

using (Stream source = this.GetType().Assembly.GetManifestResourceStream("WindowsApplication1.filename.jpg")) { 
    using (FileStream dest = File.Create(fileName)) { 
    byte[] buffer = new byte[4096]; 
    while (true) { 
     int len = source.Read(buffer, 0, buffer.Length); 
     if (len == 0) break; 
     dest.Write(buffer, 0, len); 
    } 
    } 
} 

참고 :이이 포함 자원으로 이미지를 추가 할 필요가 아닌 자원을 관리. Image.FromStream()을 사용하여 Image을 만들 수 있습니다.

1

당신이 실제로 위해 appliction에 표시 목적을 위해 Bitmap을 (즉, 당신은 당신이 파일로 저장할 수 있도록 비트 맵으로 자원을 추출하고) 사용하지 않는 경우, 가장 간단한 방법 리소스를 Stream으로 가져 와서 파일에 저장하는 것입니다.

이 튜토리얼은 스트림으로 자원을 가져 오는 방법을 보여줍니다 :

샘플에서

http://devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=75

, 저자가 스트림을 가져오고 Bitmap.FromStream 방법에 전달합니다. 대신 스트림을 파일에 직접 저장하는 것입니다 (Bitmap 전체 생략).

2

문제가 발생하지 않습니다. PNG는 손실이 적은 형식이므로 똑같은 이미지를 다시 얻을 수 있습니다. 예, Save() 할 때 반드시 똑같은 바이트를 얻지는 않습니다. 압축 형식이므로 압축률과 속도 간의 최적의 균형을 유지하는 데 압축기가 소비하는 시간이 같지 않을 수 있습니다. 하지만, 그래서?

실제 문제인 경우 이미지를 관리 자원으로 추가하지 마십시오. 프로젝트에 포함 리소스로 추가하고 Assembly.GetManifestResourceStream()을 사용하여 메타 데이터에서 읽을 수 있습니다. 원시 이미지 파일 바이트를 얻습니다. Image.FromStream()이있는 이미지로 변환 가능.

+0

나는 또한 .JPG 및 .gif 참고를 저장하고있어, 그리고 이미지 파일은 그래픽 디자이너가 상당히 많이 최적화되어 있습니다. 하지만 지금 사용하는 솔루션 (및 작동하는 솔루션)은 관리되는 대신 내장 된 리소스를 기반으로하며 작성한대로 작동합니다. – skolima

0

그것은 문제가 관리되는 리소스를 사용하여이었다 밝혀 - RESX 빌더가 비트 맵을 이미지 파일에서 객체를 생성하고 그 객체를 직렬화, 그것은 원본 파일 스트림를 저장하지 않습니다. 그러나 임베디드 리소스에는 플랫 바이너리 파일을 저장할 수 있습니다.

것은 이제 다음 .csproj 항목을 사용하여 폴더 내 이미지에서 모든 파일을 내장하고있다 :

<EmbeddedResource Include="Images\*.jpg" /> 
<EmbeddedResource Include="Images\*.png" /> 
<EmbeddedResource Include="Images\*.gif" /> 

비주얼 스튜디오가 정상적으로에서 프로젝트 파일 Embedded ResourceBuild Action 세트를 보여줍니다.

그럼, 내 코드에서, 나는 원래 파일 스트림로드 :

var assembly = GetType().Assembly; 
var regex = new Regex("\\.(png|jpg|gif))$"); 
foreach (var bitmap in assembly.GetManifestResourceNames()) 
{ 
    if(!regex.IsMatch(bitmap) 
    continue; 

    var stream = assembly.GetManifestResourceStream(bitmap); 
    //handle the stream here 
}