2009-03-23 11 views
6

Được rồi, tôi có một hình ảnh đến từ một ứng dụng bên ngoài theo định dạng được lập chỉ mục 8 bit. Tôi cần hình ảnh này được chuyển đổi sang định dạng 24 bit có cùng kích thước.Chuyển đổi từ một Format8bppIndexed sang một Format24bppRgb trong C#/GDI +

Tôi đã thử tạo một Bitmap mới có cùng kích thước và loại Format24bppRgb và sau đó sử dụng đối tượng Đồ họa để vẽ hình ảnh 8 bit trên đó trước khi lưu nó dưới dạng Bmp. Cách tiếp cận này không lỗi nhưng khi tôi mở hình ảnh kết quả, tiêu đề BMP có tất cả các loại giá trị sôi nổi. Chiều cao và chiều rộng là HUGE và, ngoài ra, còn có các giá trị vui nhộn (và lớn) cho các cờ nén và một vài giá trị khác. Rất tiếc, các yêu cầu cụ thể của tôi là chuyển tệp này đến trình điều khiển máy in cụ thể yêu cầu hình ảnh 24 bit với các giá trị tiêu đề cụ thể (mà tôi đang cố gắng đạt được thông qua GDI +)

Bất kỳ ai biết ví dụ về "up- chuyển đổi "tệp được lập chỉ mục thành tệp 24-bit không được lập chỉ mục? Nếu không phải là một ví dụ, tôi nên bắt đầu viết con đường nào?

-Kevin Grossnicklaus [email protected]

Trả lời

0

Nó có vẻ kỳ lạ mà bạn đang tạo ra một Bitmap của cùng một chiều rộng và chiều cao như đầu vào của bạn, tuy nhiên các BMP tạo ra là lớn hơn nhiều. Bạn có thể đăng một số mã không?

0

Sự cố có thể là sự khác biệt giữa Vertical- và HorizontalResolution của hình ảnh nguồn và hình ảnh đầu ra của bạn. Nếu bạn tải bitmap được lập chỉ mục 8bpp với độ phân giải 72 DPI, sau đó tạo bitmap 24bpp mới (độ phân giải mặc định sẽ là 96 DPI ... ít nhất là trên hệ thống của tôi) và sau đó sử dụng Graphics.DrawImage để chuyển sang bitmap, hình ảnh của bạn sẽ xuất hiện một chút thu nhỏ và cắt.

Có nói rằng, tôi không biết trên đầu của tôi làm thế nào để đúng tạo ra các bitmap đầu ra và/hoặc đối tượng đồ họa để quy mô đúng khi lưu. Tôi nghi ngờ nó sẽ có một cái gì đó để làm với việc tạo ra các hình ảnh bằng cách sử dụng một quy mô phổ biến như inch thay vì pixel.

11

Tôi đã sử dụng mã bên dưới để "chuyển đổi" hình ảnh từ 8bpp thành 24bpp. Kiểm tra tệp 24bpp được tạo bằng trình chỉnh sửa hex và so sánh với tệp 8bpp cho thấy không có sự khác biệt về chiều cao và chiều rộng trong hai tệp. Tức là, hình ảnh 8bpp là 1600x1200 và hình ảnh 24bpp có cùng giá trị.

private static void ConvertTo24(string inputFileName, string outputFileName) 
    { 
     Bitmap bmpIn = (Bitmap)Bitmap.FromFile(inputFileName); 

     Bitmap converted = new Bitmap(bmpIn.Width, bmpIn.Height, PixelFormat.Format24bppRgb); 
     using (Graphics g = Graphics.FromImage(converted)) 
     { 
      // Prevent DPI conversion 
      g.PageUnit = GraphicsUnit.Pixel 
      // Draw the image 
      g.DrawImageUnscaled(bmpIn, 0, 0); 
     } 
     converted.Save(outputFileName, ImageFormat.Bmp); 
    } 

Mọi thứ khác trong tiêu đề trông hợp lý và hình ảnh hiển thị giống hệt trên hệ thống của tôi. Những gì "giá trị sôi nổi" là bạn nhìn thấy?

+1

Bạn có thể bao gồm g.PageUnit = GraphicsUnit.Pixel để đảm bảo rằng nó vẽ pixel cho pixel thay vì thực hiện chuyển đổi DPI (mặc định DrawImage). –

+0

@Chris: Cảm ơn mẹo. Tôi sẽ thêm nó. –

+0

@Jim: Tôi muốn thêm rằng gợi ý của erlando để đặt độ phân giải đôi khi cần thiết để đảm bảo kết quả thực sự không thay đổi (tôi nhấn trường hợp như vậy ngày hôm nay). –

4

Đây là mã chuyển đổi của tôi. Chú ý sự phù hợp của độ phân giải giữa ảnh gốc và ảnh kết quả.

private void ConvertTo24bppPNG(Stream imageDataAsStream, out byte[] data) 
    { 
     using (Image img = Image.FromStream(imageDataAsStream)) 
     { 
      using (Bitmap bmp = new Bitmap(img.Width, img.Height, PixelFormat.Format24bppRgb)) 
      { 
       // ensure resulting image has same resolution as source image 
       // otherwise resulting image will appear scaled 
       bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution); 

       using (Graphics gfx = Graphics.FromImage(bmp)) 
       { 
        gfx.DrawImage(img, 0, 0); 
       } 

       using (MemoryStream ms = new MemoryStream()) 
       { 
        bmp.Save(ms, ImageFormat.Png); 
        data = new byte[ms.Length]; 
        ms.Position = 0; 
        ms.Read(data, 0, (int) ms.Length); 
       } 
      } 
     } 
    } 
Các vấn đề liên quan