2011-07-27 8 views
3

이미지의 투명도를 제거하기 위해 Bitmap 객체의 기본 바이트를 조작하는 것에 어려움을 겪고 있습니다. Bitmap 객체를 사용하는 정적 투명도 제거 메서드가 있습니다. 관련 코드 : http://pastebin.com/ZjjPSdx8C#의 비트 맵 바이트 조작

파일을 기반으로 비트 맵 개체를 호출하면 비트 맵이 변경되지 않습니다. 만약 내가 제대로 이해가 http://support.microsoft.com/kb/814675

에 따라 파일을 기반으로 그래서 비트 맵을 복사하는 방법을 만들어 때문입니다 : http://pastebin.com/9rXRJ6cx

private Bitmap LoadBmp(string name) 
    { 
     Assembly asm = Assembly.GetExecutingAssembly(); 
     string loc = Path.GetDirectoryName(asm.Location); 
     string path = Path.Combine(loc, "Images\\" + name); 
     Bitmap notsafe = (Bitmap)Bitmap.FromFile(path); 
     return ImageProcessor.SafeBitmap(notsafe); 
... 

모든 벌금과 멋쟁이. PNG는 잘 처리하지만 GIF는 사용하지 않습니다. 그들은 끔찍하게 왜곡 된 을 나옵니다.

 byte[] b = new byte[2048]; 
     int c; 
     byte[] imgArr; 
     using (FileStream fs = new FileStream(path, FileMode.Open)) 
     { 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       while ((c = fs.Read(b, 0, b.Length)) > 0) 
        ms.Write(b, 0, c); 
       imgArr = ms.ToArray(); 
      } 
     } 

     return (Bitmap)Bitmap.FromStream(new MemoryStream(imgArr)); 

이는 지프의를 왜곡하지 않습니다

바이트 배열에 파일을 작성하고, 그 다음에 비트 맵을 내놓고 다른 방법을 시도했다. 그러나 내 투명성 제거 방법은 더 이상 PNG에서 작동하지 않습니다! 분명히 뭔가 잘못하고 있습니다. 누군가가 도울 수 있기를 바랍니다.

+1

'File' 객체에 멋진'ReadAllBytes()'메소드가있는 경우,'System.IO.File.ReadAllBytes()' –

답변

4

편집 : 같은 파일에서로드 할 때

당신은 당신의 불변의 비트 맵 문제를 해결할 수 있습니다 : (느린) 어떤 Marshal.Copy을 할 필요에서 당신을 방지

var bmp = new Bitmap(Image.FromFile("C:\bmp.bmp"))

을 또한 GIF가 잘 리거나 왜곡되는 문제를 해결합니다. 당신이 관심이 있다면,이 작업을 수행 내부 .NET 코드는 다음

g = Graphics.FromImage(this); 
g.Clear(Color.Transparent); 
g.DrawImage(original, 0, 0, width, height); 

을 그래서 내가 당신의 속도 요구 사항을 충족하지 않은 당신의 투명성 문제를 해결하기 위해, 아래를 준 코드는 본질적으로 . 이론적으로 (5.6 seconds g.FromImage vs 6.4 seconds yours with 1000 gifs @ 543x341)

의 당신은 당신이 부하를하고 g.FromImage를 통해 동시에 복사 할 수있는 경우

그러나, 내가 가진 속도는 복사 및 제거 투명성에 결합 경우, 빨리 당신을 만들 수 있습니다 같은 기능. 이미지를 다시 작성하지 않고 GIF를로드하면 사실 다른 픽셀 형식 (8bppindexed)이되므로 해당 기능이 그대로 작동하지 않습니다. 어느 쪽이든, 위의 솔루션은 CheckIfTransparent 함수를 사용할 때이 문제를 해결할 것이며 아래 해결책 (조금 수정해야합니다)이 더 빨리 수행 할 것입니다. 내가 그렇게하면 시간을 보내고 있습니다. 나는 그 문제가 흥미 롭다고 생각한다.

나는 알파를 제거하기위한 당신의 고문이 완전히 정확하지 않다는 것을 알았습니다. 투명 그라디언트와 함께 사용할 때 어디에서 정확하게, 그러나 당신의 골아가 잘못 보이는지 모르겠습니다. 스트레이트 GDI를 사용하는 것은 예상대로 나타납니다. 색상을 올바르게 변환하고 있는지 확인합니다.그냥 모든 Marshal.Copy 및 안전하지 않은 코드를 수행하는 PNG 또는 GIF에 투명도를 제거하려면


, 왜 그냥 흰색 배경을 그릴, 새로운 비트 맵을 만들 수 없습니다, 다음 종료 PNG 오버레이/그것에 gif? 덜 복잡한 코드처럼 보입니다.

편집 : 이런 식으로 뭔가 :

public static Bitmap ManagedSafeBitmap(string file) 
    { 
     using (var img = Image.FromFile(file)) 
     { 
      var bmp = new Bitmap(img.Width, img.Height); 
      bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution); 
      using (Graphics g = Graphics.FromImage(bmp)) 
      { 
       g.Clear(Color.White); 
       g.DrawImage(img, 0, 0); 
      } 

      return bmp; 
     } 
    } 

흰색 배경 당신에게 새로운 이미지를 부여하고 효과적으로 어떤 색상을 모두 투명 Color.White에 픽셀을 변경, 그 위에 소스 이미지를 넣어 것입니다 원하는 것을 전달할 수 g.Clear()

+0

더 큰 것에 대해 생각하는 훌륭한 직업 그림! –

+0

네, 원래이 작업을 수행했지만 속도를 더 높이고 싶었습니다. 관리되는 방법은 MakeSafe와 CleanTransparent의 조합보다 약 50 % 정도 느립니다. 수세식이 없으면 (비록 그것이 없으면 작동하지 않는다고해도) 300 % 느려집니다. 속도 차이가 중요하도록 이미지를 많이 처리 할 것입니다 ... (100 만 개). – user865864

+0

위의 수정 사항을 참조하십시오. –

0

WriteableBitmap 클래스로 시도해 보겠습니다. 나는 그것이 관리되는 코드를 사용하여 픽셀 조작을 위해서 만들어진 것이라고 들었습니다.