2009-08-02 36 views
5

Tôi đang xây dựng trang web cho câu lạc bộ là một phần của tổ chức mẹ. Tôi đang tải xuống (leeching;)) những hình ảnh được đặt trên trang tiểu sử của tổ chức mẹ để hiển thị trên trang của riêng tôi. Nhưng trang web của họ có nền trắng đẹp và trang web của tôi có một màu xám đẹp trên nền. Điều này không phù hợp. Ý tưởng của tôi là chỉnh sửa hình ảnh trước khi lưu chúng vào máy chủ của tôi.Loại bỏ hiện vật JPEG trong C#

Tôi đang sử dụng GDI + để nâng cao hình ảnh của mình và khi tôi sử dụng phương pháp MakeTransparent của Bitmap, nó hoạt động và thực hiện những gì nó làm, nhưng tôi vẫn có các tạo phẩm trắng jpeg đó. Các đồ tạo tác làm cho hình ảnh tệ đến thế, tôi tốt hơn là không làm cho hình ảnh trong suốt và chỉ để lại hình ảnh trắng, nhưng điều đó thực sự xấu xí trên trang web của riêng tôi. Tôi luôn luôn có thể ở một biên giới đẹp với nền màu trắng tất nhiên, nhưng tôi thay đổi nền thành trong suốt.

Vì vậy, tôi đã tự hỏi nếu và làm thế nào tôi có thể loại bỏ một số hiện vật JPEG đơn giản trong C#. Đa co ai đo tưng lam việc nay trươc đây chưa?

Cảm ơn thời gian của bạn.

Ví dụ hình ảnh:

TB-5404

phẩm cải biên image:

TB-5404 transformed

+0

Bạn có thể đăng một trong những hình ảnh này để chúng ta có thể thấy ý bạn ? Kết quả này thực sự không đáng ngạc nhiên chút nào, vì tính trong suốt chỉ làm cho một màu trong suốt đặc biệt (màu trắng trong trường hợp này). Nếu bạn chọn màu trắng là màu trong suốt, tất cả các pixel trắng sẽ trở nên trong suốt. – MusiGenesis

+0

Đó là sự thật .. và nó hoạt động như một nét duyên dáng .. quá xấu cho JPEG nó đã bị rối tung lên;) .. đã đăng một bức ảnh! – Arcturus

+0

Tôi bị mù! Xin lỗi, nó không hiển thị. – MusiGenesis

Trả lời

5

Vâng, tôi đã cố gắng một cái gì đó còn xa mới hoàn hảo, nhưng tôi hình dung nó có thể có ích cho người khác .

tôi đã nhận được tới:

alt text

vấn đề gặp phải: bóng tối là đủ xa từ 'tắt trắng' là khó khăn để nó tự động chuyển đổi chúng, và thậm chí nếu bạn đã làm cái bóng vẫn sẽ ở chính hình ảnh đó. Ánh sáng chói lóa trên đầu ... điều trung tâm, cũng gần với màu trắng sau đó là các bit chống răng cưa. Có ba đến bảy điểm trắng trong hình ảnh không được kết nối với bất kỳ góc chính nào; và cuối cùng vẫn có một chút màu trắng trên các cạnh (có thể là có thể thoát khỏi nó bằng cách tinh chỉnh mã, nhưng không phải không có cất cánh một phần của đầu chói

C# mã không hiệu quả:.

static void Main() 
    { 
     Bitmap bmp=new Bitmap("test.jpg"); 

     int width = bmp.Width; 
     int height = bmp.Height; 
     Dictionary<Point, int> currentLayer = new Dictionary<Point, int>(); 
     currentLayer[new Point(0, 0)] = 0; 
     currentLayer[new Point(width - 1, height - 1)] = 0; 
     while (currentLayer.Count != 0) 
     { 
      foreach (Point p in currentLayer.Keys) 
       bmp.SetPixel(p.X, p.Y, Color.Black); 
      Dictionary<Point, int> newLayer = new Dictionary<Point, int>(); 
      foreach (Point p in currentLayer.Keys) 
       foreach (Point p1 in Neighbors(p, width, height)) 
        if (Distance(bmp.GetPixel(p1.X, p1.Y), Color.White) < 40) 
         newLayer[p1] = 0; 
      currentLayer = newLayer; 
     } 

     bmp.Save("test2.jpg"); 
    } 

    static int Distance(Color c1, Color c2) 
    { 
     int dr = Math.Abs(c1.R - c2.R); 
     int dg = Math.Abs(c1.G - c2.G); 
     int db = Math.Abs(c1.B - c2.B); 
     return Math.Max(Math.Max(dr, dg), db); 
    } 

    static List<Point> Neighbors(Point p, int maxX, int maxY) 
    { 
     List<Point> points=new List<Point>(); 
     if (p.X + 1 < maxX) points.Add(new Point(p.X + 1, p.Y)); 
     if (p.X - 1 >= 0) points.Add(new Point(p.X - 1, p.Y)); 
     if (p.Y + 1 < maxY) points.Add(new Point(p.X, p.Y + 1)); 
     if (p.Y - 1 >= 0) points.Add(new Point(p.X, p.Y - 1)); 
     return points; 
    } 

Các mã hoạt động bằng cách bắt đầu với hai điểm, thiết lập chúng thành màu đen, và sau đó kiểm tra xem có bất kỳ người hàng xóm gần họ gần trắng hay không, nếu chúng được thêm vào danh sách sau đó được thực thi. để thay đổi

Thay vào đó, bạn có thể muốn xem xét thiết kế lại trang web để sử dụng nền trắng.

+0

Trong khi nó không hoàn hảo, câu trả lời của bạn có nhiều upvotes nhất, vì vậy tôi đã chấp nhận câu trả lời của bạn; Tôi đã từ bỏ nhiệm vụ giải mã hình ảnh của mình. Tôi đặt một đường viền xung quanh hình ảnh màu trắng, giống như một bức tranh .. Cảm ơn sự giúp đỡ !! :) Xem http://www.501st.nl/Members.aspx;) – Arcturus

0

Bạn sẽ phải xử lý sắc thái của off-trắng là tốt. Có lẽ khi họ thực hiện các iamges ban đầu và thiết lập màu nền, có một số chống răng cưa, và sau đó khi tiết kiệm như một jpg, không phải tất cả các màu sắc sẽ được bảo quản hoàn hảo. Vì vậy, nếu bạn đang làm cho một màu sắc cụ thể trong suốt, nó sẽ không nhận được tất cả các sắc thái của màu sắc mà sẽ để lại nhiều hiện vật. Bạn cần một cái gì đó mà sẽ làm minh bạch tỷ lệ thuận với làm thế nào gần một màu là màu sắc quan trọng của bạn. Điều này có thể là một cái gì đó dễ dàng hơn để làm như một kịch bản hàng loạt trong một cái gì đó như Photoshop, nhưng tôi không biết nếu đây là một cái gì đó bạn đang cần phải làm trong thời gian thực.

+0

cũng .. có thể thay đổi bạn biết .. theo thời gian .. nó sẽ là tốt đẹp để có một cái gì đó năng động .. để Xử lý tất cả các hình ảnh cho các thành viên trong tương lai .. – Arcturus

+0

Sau khi xem ảnh, nếu nguồn của bạn có thể cung cấp chúng theo định dạng không mất dữ liệu, như bitmap, có thể bạn sẽ không gặp phải vấn đề gì. Có vẻ như màu trắng là từ nén xảy ra với jpg. Có lẽ họ có thể lưu trữ cả jpg và bmp trên máy chủ của họ, bằng cách sử dụng của jpg trên trang web của họ, và để lại của bmp trong cùng một vị trí. Vì vậy, khi bạn kéo các hình ảnh, bạn có thể thay thế phần mở rộng, kéo bmp, và thay thế màu sắc. – AaronLS

+0

Vâng tôi có thể thử điều đó, nhưng tôi không nghĩ rằng họ có nguồn gốc, bởi vì nó là một bộ sưu tập các hình ảnh được gửi bởi nhiều người làm cho những khung hình .. cảm ơn cho các gợi ý mặc dù .. – Arcturus

0

Không có cách nào (từ xa dễ dàng) để giải quyết vấn đề này theo chương trình. Các vùng giả tạo màu trắng xung quanh mép của hình ảnh là kết quả của các điểm ảnh gần như trắng nhưng không hoàn toàn, do đó chúng không nhận được hiệu ứng trong suốt. Ngoài ra còn có một vài điểm trên mặt nạ/cốc cà phê có màu trắng tinh khiết, vì vậy chúng trở nên trong suốt và do đó màu xám.

Đặt cược tốt nhất của bạn là liên hệ với quản trị viên trang web ban đầu và xem họ có thể gửi cho bạn hình ảnh gốc hay không, hy vọng trong photoshop hoặc một số định dạng khác nơi các lớp gốc được giữ riêng. Sau đó, bạn có thể tạo lại hình ảnh ở định dạng giữ nguyên độ trong suốt (PNG hoặc thứ gì đó tương tự) hoặc sử dụng độ dốc của bạn cho nền (rất khó để có được quyền này vì bạn không biết chính xác vị trí bên trong gradient hình ảnh sẽ được hiển thị).

Tôi muốn sử dụng một số loại viền xung quanh hình ảnh như bạn đã đề xuất.

+0

Hmm yeah .. luôn có các thành viên đến, và tôi muốn được thực hiện với nó một lần và cho tất cả thực sự ... Cảm ơn thời gian của bạn mặc dù .. nhiều đánh giá cao của nó .. có lẽ tôi sẽ sử dụng các giải pháp biên giới sau khi tất cả .. – Arcturus

1

Lặp qua từng pixel trong hình ảnh, nếu R, G và B cao hơn, giả sử, sau đó thay thế màu bằng màu mong muốn của bạn (hoặc trong suốt). Có lẽ ngay cả trọng lượng màu mới tùy thuộc vào cách xa 'màu trắng' thật sự là màu cũ.

Mong đợi để có được vấn đề nếu các hình ảnh thực tế là màu trắng cũng có, otherwhise bạn sẽ kết thúc với một stormtrooper xám :)

+1

Điều này có thể được thay đổi thành một giải pháp mục đích chung hơn sẽ không làm xám trooper trooper bằng cách thực hiện một đồ thị psuedo traversal. Bắt đầu ở điểm ảnh trên cùng bên trái, sau đó chuyển sang trái/xuống/lên/phải đến từng điểm ảnh phù hợp với tiêu chí 'đủ gần'. Về cơ bản là lũ lụt. Điều này có thể vẫn gây ra rắc rối nếu có sự pha trộn trên các cạnh của hình ảnh thực tế (một sự pha trộn của màu trắng và màu nâu có vẻ đồng bằng sai trên màu xám). – CoderTao

+0

Tôi thích câu trả lời của bạn .. sạch sẽ và đơn giản của nó .. Khi tôi đang ăn tối với gf của tôi chiều nay nó đánh tôi quá .. Giải pháp của bạn với một, thêm "không có thay đổi ở đây" khu/khối cho stormtrooper :) – Arcturus

+0

Ok Tôi đã thử giải pháp của bạn là tốt .. nó vẫn trông giống như crap với biên giới màu trắng ở các cạnh .. damn trắng này là xấu xí;) .. Cảm ơn thời gian của bạn mặc dù! – Arcturus

1

Bạn sẽ không thể làm điều này tự động với bất cứ điều gì giống như độ chính xác 100%.

Lý do cho điều này là thông tin duy nhất bạn có là màu mà bạn biết rằng một số pixel trong hình ảnh đang cố gắng kết hợp độc đáo với. Chỉ một số pixel trong hình ảnh thực sự sẽ sử dụng màu ở hoặc gần giá trị này cho mục đích tô bóng vào nền, những người khác sẽ sử dụng (trong trường hợp màu trắng) vì đối tượng thực tế được biểu thị thực tế là màu trắng (damn độ chính xác của những người lính bão hoàng gia).

Loại máy tinh vi học tập để phát hiện đó là một miền có vấn đề thú vị và có thể là một dự án thú vị cho bạn nhưng chắc chắn sẽ không đưa ra giải pháp nhanh cho vấn đề trước mắt của bạn.

Vấn đề khác bạn có là, ngay cả khi bạn có thể phát hiện với độ tin cậy tốt, những khu vực hình ảnh đang cố gắng hòa vào mặt sau, bạn sẽ gặp vấn đề 'không thể' và sau đó trả lại chúng thành nền mới màu trừ khi màu sắc tương thích hợp lý. Trong trường hợp này, màu xám của bạn có thể hoạt động vì nó có màu phổ rộng như màu trắng.

Các kỹ thuật mà bạn muốn sử dụng như sau:

  • Sử dụng một thuật toán điền lũ để lựa chọn, từ các cạnh của hình ảnh vào bên trong tất cả các pixel trong x% (1) của màu nền được biết đến.
  • Đối với những pixel đó, đặt kênh alpha của chúng thành giá trị dưới dạng tỷ lệ đối sánh của chúng với màu gốc và loại bỏ màu được gắn với nó.
    • Vì vậy, nếu phông nền là giá trị RGB a, b, c và pixel là +5, b, c-7 thì kết quả là RGBA 5,0,0, ((a + b + c- 7)/(a ​​+ b + c) * 256) (1)
  • tổng hợp hình ảnh pha trộn alpha này qua một hình vuông đau của cột đất nền mới.
  • hiển thị kết quả không có kênh alpha làm hình ảnh mới.

Điều này vẫn sẽ có vấn đề đối với các đối tượng có màu gần màu nền. * trong trường hợp của bản gốc thì nó có thể là bóng đổ đang được sử dụng để ngụ ý sự hiện diện của đối tượng, như vậy lấp đầy lũ sẽ 'xâm nhập' bên trong của hình ảnh. * trong trường hợp hình ảnh kết quả sẽ mất định nghĩa đối tượng và không có bóng mờ tinh tế, nổi bật hoặc chỉ các đường trơn sẽ có mặt để cho biết nơi đối tượng kết thúc và mặt sau kết thúc.

Đây là lần xấp xỉ đầu tiên rất thô sơ nhưng có thể bao gồm một tỷ lệ phần trăm hợp lý của mục tiêu của bạn. Những hình ảnh có lỗ hổng trong suốt (như khoảng trống trong vòm ngoài trong ví dụ của bạn) không có khả năng hoạt động độc đáo theo kiểu tự động vì thuật toán sẽ không thể phân biệt giữa các lỗ trắng và bão trắng.
Bạn có thể muốn làm cho thuật toán của bạn làm nổi bật các vùng của hình ảnh mà nó lên kế hoạch tái chiết khấu và cho phép lựa chọn vùng đơn giản để bao gồm/loại trừ (sử dụng công cụ chọn cây đũa thần từ Pain.Net làm ví dụ về cách thực hiện điều này nếu bạn muốn trở thành ưa thích, cho phép đơn giản mỗi lựa chọn pixel camera cho nỗ lực ít hơn trả trước


  1. giá trị cho x sẽ là một cái gì đó bạn điều chỉnh -. nó có thể là, dựa trên một số khía cạnh của hình ảnh (chẳng hạn các tỷ lệ hình ảnh gần với màu nền sau), bạn có thể tinh chỉnh nó tự động.
  2. Lưu ý rằng công thức này giả định một gần màu trắng, cho gần đen bạn sẽ muốn đảo ngược
0

Cảm ơn tất cả các câu trả lời của bạn .. tất cả gợi ý tốt ..

Đây là những gì tôi nấu chín lên ngày hôm qua:

public const int PIXEL_REGION = 60; 
public const int TRANSPARENT_DISTANCE = 60; 
public static readonly Color TRANSPARENT_COLOR = Color.White; 

private System.Drawing.Image ProcessImage(System.Drawing.Image image) 
{ 
    Bitmap result = new Bitmap(image.Width, image.Height); 

    Bitmap workImage = new Bitmap(image); 

    for (int x = 0; x < image.Width; x++) 
    { 
     for (int y = 0; y < image.Height; y++) 
     { 
      Color color = workImage.GetPixel(x, y); 

      if (x < PIXEL_REGION || x > image.Width - PIXEL_REGION || y < PIXEL_REGION || y > image.Height - PIXEL_REGION) 
      { 
       double distance = CalculateColourDistance(TRANSPARENT_COLOR, color); 

       if(distance < TRANSPARENT_DISTANCE) 
       { 
        result.SetPixel(x, y, Color.Transparent); 
        continue; 
       } 
      } 

      result.SetPixel(x, y, color); 
     } 
    } 

    return result; 
} 

private double CalculateColourDistance(Color c1, Color c2) 
{ 
    int a = c2.A - c1.A; 
    int r = c2.R - c1.R; 
    int g = c2.G - c1.G; 
    int b = c2.B - c1.B; 

    return Math.Sqrt(Math.Pow(a, 2) + Math.Pow(r, 2) + Math.Pow(g, 2) + Math.Pow(b, 2)); 
} 

của nó không phải là mã đẹp nhất trong cuốn sách, nhưng những gì nó làm, là đối với mọi pixel trong vùng pixel, nó tính khoảng cách giữa Color.White và màu của riêng tôi và khi nó thấp hơn khoảng cách được xác định trước, nó sẽ có màu trong suốt ..

Đoạn mã này tạo ra kết quả như sau:

TB-5404 transformed v 2.0

của nó không xấu nhớ bạn .. nhưng nó vẫn hút :)

Tôi có một trick lên tay áo của tôi mà tôi sẽ chia sẻ với các bạn cũng như nếu nó thành công ...

0

Dưới đây là một thất bại;)

tôi có một ý tưởng .. phim sử dụng greenscreen, tại sao không sử dụng một lớp phủ màu xanh lá cây cho hình ảnh của tôi .. vì vậy, đây là lớp phủ:

Green overlay with transparent inner thing

Và kết quả:

Green stuff all over the place

Vì vậy, tôi học được một bài học quý giá về nén PNG .. Tôi cũng đã thử nó với bmp, nhưng bằng cách nào đó tôi luôn luôn kết thúc với một biên giới xanh .. Tôi có thể cố gắng xóa nó, nhưng có lẽ tôi chỉ nên để nó ở nền trắng, đặt một số đường viền ngớ ngẩn xung quanh nó và được thực hiện với nó ...

Ah cũng ..;)

+0

Câu hỏi hơi khác, là hằng số biên giới kỳ quặc ...? (IE làm hầu hết/tất cả các hình ảnh có cùng đường viền, với hình ảnh do người dùng cung cấp ở bên trong?) – CoderTao

+0

Không, có nhiều loại biên giới khác nhau ... ví dụ: so sánh hình ảnh bikerscout (ở trên) với biên giới stormtrooper: http: //images.501stforums.com/memberdata/54/04/tk5404_full.jpg – Arcturus

+0

Vâng, dòng suy nghĩ (ít hữu ích như bây giờ), là bạn làm sạch biên giới bằng tay, (mà nó trông giống như bạn làm với phương pháp màu xanh lá cây), sau đó đánh dấu một phần nội thất là 'khu vực để hợp nhất' (xanh lá cây, đỏ tươi, hồng huỳnh quang, bất cứ điều gì phù hợp với bạn), sau đó hợp nhất khu vực trung tâm với bản gốc. Bạn có đường viền được làm sạch bằng tay và vùng trung tâm được làm sạch bằng định nghĩa. Chỉ hoạt động nếu bạn biết biên giới. – CoderTao

1

Một cách tiếp cận khác dựa trên hộp thoại comment:

static void Main() 
{ 
    Bitmap mask = new Bitmap(@"mask.bmp"); 
    Bitmap bmp=new Bitmap(@"test.jpg"); 
    int width = bmp.Width; 
    int height = bmp.Height; 

    for(int x=0; x<width; x++) 
     for (int y = 0; y < height; y++) 
      if (mask.GetPixel(x, y).R < 250) 
       bmp.SetPixel(x,y,mask.GetPixel(x,y)); 
    bmp.Save(@"test3.jpg"); 
} 

mặt nạ Given:

alt text

Bạn nhận được kết quả:

alt text

Với đường viền của mặt nạ được làm sạch một chút trong Paint.NET với tính năng chống răng cưa bị tắt. Một lần nữa, nó chỉ áp dụng nếu bạn có thể phân biệt ranh giới nào đang được sử dụng ... nhưng nó đã trở nên độc đáo ... trừ màu xanh lá cây ...

+0

Vâng tôi đã thử điều này với cách tiếp cận thứ hai, nhưng khi tôi làm cho màu xanh trong suốt, nó đi sai một lần nữa;) .. (xem đường viền màu xanh lá cây) .. Vấn đề là nền của trang web của riêng tôi, tôi đoán .. Chúng tôi sử dụng gradient ở chế độ nền và không cần đặt chính xác ảnh, nền trong suốt là cách đi .. Ah well .. Chúng tôi có một ý tưởng khác. Chúng tôi cho phép người dùng tải lên hình ảnh hành động của riêng họ, thêm khung hình ảnh bão tố đẹp và cho rằng đó là ảnh hồ sơ. Không có gì để làm với vấn đề này, vì vậy tránh nó cũng sẽ giải quyết nó tôi đoán .. cảm ơn vì đã giúp đỡ .. nhiều đánh giá cao – Arcturus

+0

Tôi nghĩ rằng bạn có thể sửa đổi hình ảnh mặt nạ sao cho đường viền màu xanh lá cây trong suốt (khi thực hiện thao tác chạm tay); sau đó chỉ cần sử dụng khu vực màu đỏ để hợp nhất với hình ảnh gốc; kết quả là một khu vực trong suốt trên biên giới và khu vực hợp nhất ở trung tâm. Mặc dù, dù bằng cách nào, nó đã được vui vẻ. – CoderTao

Các vấn đề liên quan