Đặt nền trong suốt bằng ImageMagick và lời nhắc dòng lệnh


119

Giả sử bạn có bất kỳ hình ảnh nào (PNG hoặc JPG). Hình ảnh này có nền trắng và tôi cần đặt nền này trong suốt.

Tôi đã thử với các ví dụ sau:

  • convert original.png -background none transparent.png
  • convert original.png -background white -flatten -alpha off transparent.png

nhưng không có kết quả mong muốn.

Làm thế nào tôi có thể làm cho nó?

QUAN TRỌNG: Sử dụng convertdòng lệnh.


Kỳ lạ - Tôi nghĩ rằng lệnh có liên quan là convert original.png -transparent white new.pngnhưng khi thử nó, nó không thể hoạt động được. Ngoài ra, bạn có chắc nền của mình thực sự là màu trắng (#FFFFFF) hay chỉ gần như trắng (ví dụ: #FEFEFE)?
mathematical.coffee

@ math.coffee Được rồi, tôi hiểu rồi, hãy để tôi kiểm tra xem có phải như vậy không và tôi sẽ tiếp tục chủ đề này. Cảm ơn bạn.
Israel

@ math.coffee Xin chào một lần nữa, tôi đã kiểm tra màu sắc và hình ảnh này có nền như #FFFFFF, hay nói cách khác là "màu trắng". :( Đây không phải là trường hợp!
Israel

Câu trả lời:


140

Tôi đang sử dụng ImageMagick 6.6.9-7 trên Ubuntu 12.04.
Những gì làm việc cho tôi là như sau:

convert test.png -transparent white transparent.png

Điều đó đã thay đổi tất cả màu trắng trong test.png thành trong suốt.


6
Điều này không hiệu quả với tôi cho đến khi tôi nhận ra JPG sẽ không minh bạch. Khi tôi chuyển sang PNG, nó đã làm chính xác những gì tôi muốn - chỉ cần thay đổi "trắng" thành "rgb ($ r, $ g, $ b)".
Roger Dueck

2
Chết tiệt! điều đó thật tuyệt!
agilob

2
Điều này sẽ không chỉ chuyển đổi nền thành trong suốt mà còn mọi pixel màu trắng. Có cách nào để chuyển đổi chỉ nền thành trong suốt không?
Alejandro Lozdziejski,

2
@AlejandroLozdziejski - bạn định nghĩa "nền" như thế nào?
Jules

1
@AlejandroLozdziejski: Câu hỏi hay. Vui lòng xem giải pháp của tôi sử dụng dải ngập từ các cạnh, tìm kiếm các màu gần giống với pixel trên cùng bên trái.
hackerb9

79

Tôi đã từng gặp vấn đề tương tự. Trong đó tôi phải xóa nền trắng khỏi định dạng ảnh jpg / png bằng ImageMagick.

Điều làm việc cho tôi là:

1) Chuyển đổi định dạng hình ảnh sang png: convert input.jpg input.png

2) convert input.png -fuzz 2% -transparent white output.png


6
Điều này là tốt, để có một cạnh mịn hơn giữa nền trong suốt và nền trước mờ đục. Nếu bạn chuyển đổi các biểu tượng ồn ào trong JPG tới PNG, và muốn thêm tính minh bạch, bạn cũng có thể thêm một số bộ lọc trung bình:mogrify -format png -median 2 -fuzz 5% -transparent white ico_*.jpg
Tomasz Gandor

44

Giải pháp

color=$( convert filename.png -format "%[pixel:p{0,0}]" info:- )
convert filename.png -alpha off -bordercolor $color -border 1 \
    \( +clone -fuzz 30% -fill none -floodfill +0+0 $color \
       -alpha extract -geometry 200% -blur 0x0.5 \
       -morphology erode square:1 -geometry 50% \) \
    -compose CopyOpacity -composite -shave 1 outputfilename.png

Giải trình

Câu trả lời này dài hơn một chút so với các câu trả lời đơn giản được đưa ra trước đó, nhưng nó mang lại kết quả tốt hơn nhiều : (1) Chất lượng vượt trội do alpha khử răng cưa và (2) chỉ nền được loại bỏ thay vì một màu duy nhất. ("Nền" được định nghĩa là có màu gần giống với pixel trên cùng bên trái, sử dụng lớp phủ ngập từ các cạnh hình ảnh.)

Ngoài ra, kênh alpha cũng bị xói mòn một nửa pixel để tránh quầng sáng. Tất nhiên, các hoạt động hình thái học của ImageMagick chưa (?) Hoạt động ở cấp subpixel, vì vậy bạn có thể thấy tôi đang tăng cường kênh alpha lên 200% trước khi xói mòn.

So sánh kết quả

Dưới đây là so sánh giữa phương pháp đơn giản ("-fuzz 2% -transparent trắng") so với giải pháp của tôi, khi chạy trên logo ImageMagick . Tôi đã làm phẳng cả hai hình ảnh trong suốt trên nền màu nâu yên ngựa để làm cho sự khác biệt rõ ràng (nhấp vào để xem ảnh gốc).

Việc thay thế đơn giản màu trắng thành trong suốt không phải lúc nào cũng hiệu quả Kênh chữ cái chống răng cưa và ngập lụt trông đẹp hơn nhiều

Chú ý cách bộ râu của Pháp sư đã biến mất trong cách tiếp cận đơn giản. So sánh các cạnh của Wizard để xem cách khử răng cưa alpha giúp hình hòa trộn mượt mà vào nền.

Tất nhiên, tôi hoàn toàn thừa nhận rằng đôi khi bạn có thể muốn sử dụng giải pháp đơn giản hơn. (Ví dụ: Nó dễ nhớ hơn rất nhiều và nếu bạn đang chuyển đổi sang GIF, dù sao thì bạn cũng bị giới hạn ở alpha 1 bit.)

tập lệnh shell mktrans

Vì không chắc bạn sẽ muốn gõ lệnh này nhiều lần, tôi khuyên bạn nên gói nó trong một tập lệnh. Bạn có thể tải xuống tập lệnh shell BASH từ github để thực hiện giải pháp được đề xuất của tôi. Nó có thể chạy trên nhiều tệp trong một thư mục và bao gồm các nhận xét hữu ích trong trường hợp bạn muốn chỉnh sửa mọi thứ.

tập lệnh bg_removal

Nhân tiện, ImageMagick thực sự đi kèm với một tập lệnh có tên "bg_removal" sử dụng tràn ngập theo cách tương tự như giải pháp của tôi. Tuy nhiên, kết quả không được tuyệt vời vì nó vẫn sử dụng alpha 1 bit. Ngoài ra, tập lệnh bg_removal chạy chậm hơn và khó sử dụng hơn một chút (nó yêu cầu bạn chỉ định hai giá trị fuzz khác nhau). Đây là một ví dụ về kết quả từ bg_removal.

Tập lệnh bg_removal: có râu, nhưng thiếu khử răng cưa


2
Tôi cần sửa đổi lông tơ thành 2%, vì hình ảnh chứa một máy màu trắng với nền trắng. Và mặc dù điều này không hoàn hảo 100%, nhưng đó là giải pháp tốt nhất mà tôi tìm thấy vì tôi không muốn làm nó thủ công gimphoặc bất cứ điều gì. :)
tukusejssirs

1
Giải pháp tuyệt vời !
0x01h

29

Điều này phù hợp với tôi:

convert original.png -fuzz 10% -transparent white transparent.png

trong đó% lông tơ càng nhỏ, càng gần với màu trắng thực hoặc ngược lại,% càng lớn, thì càng có nhiều biến thể từ màu trắng trở nên trong suốt


1
Chà! Đây chính xác là những gì tôi cần! trước: i.imgur.com/2Rd7w1N.png , sau: i.imgur.com/4RTYygo.png
Dorian

Nó không hoạt động hoàn hảo vì nó không thể xử lý hình ảnh có màu trắng và nền trắng. như ảnh của con át chủ bài.
Sr. Trưởng nhóm lập trình viên PHP

Đối với màu trắng trên nền trắng, hãy thử sử dụng giải pháp lấp đầy lũ lụt mà tôi đã đăng ở trên . Hoặc sử dụng mktranstập lệnh shell của tôi : github.com/hackerb9/mktrans
hackerb9

12

Bạn có thể sử dụng cái này để làm cho nền trong suốt

convert test.png -background rgba(0,0,0,0) test1.png

Phần trên cung cấp nền trong suốt cho quận trưởng


4
Vỏ có thể yêu cầu một số trích dẫn (): convert more-icon.png -gravity center -background 'rgba(0,0,0,0)' -extent 27x27 new-more-icon.png
Jim K.

7

Sử dụng ImageMagick, điều này rất giống với mã và kết quả của hackerb9, nhưng là dòng lệnh đơn giản hơn một chút. Nó giả định rằng pixel trên cùng bên trái là màu nền. Tôi chỉ lấp đầy nền với độ trong suốt, sau đó chọn kênh alpha và làm mờ nó và loại bỏ một nửa khu vực bị mờ bằng cách sử dụng -level 50x100%. Sau đó, bật lại tất cả các kênh và làm phẳng nó với màu nâu. -Blur 0x1 -level 50x100% hoạt động để chống răng cưa ranh giới của độ trong suốt của kênh alpha. Bạn có thể điều chỉnh giá trị mờ, lượng mờ và giá trị -level 50% để thay đổi mức độ khử răng cưa.

convert logo: -fuzz 25% -fill none -draw "matte 0,0 floodfill" -channel alpha -blur 0x1 -level 50x100% +channel -background saddlebrown -flatten result.jpg

nhập mô tả hình ảnh ở đây


Đẹp. Tôi thích rằng bạn đã nắm được ý chính của nó trong một dòng ngắn gọn. Điều này tương tự như một trong những bước trung gian của tôi khi tôi viết kịch bản. Tôi quyết định chống lại nó bởi vì (a) nó mất quá nhiều chi tiết sắc nét, (b) Tôi muốn làm cho lựa chọn màu sắc rõ ràng để nó có thể dễ dàng thay đổi, và (c) Tôi muốn tràn ngập từ tất cả các cạnh, không chỉ trên đỉnh -góc trái. (Có thể có những thứ khác mà tôi đang quên ngay bây giờ).
hackerb9

2
Tái bút Tôi sẽ đoán rằng "fmw" là viết tắt của Fred M. Weinhaus. Nếu vậy, xin chào Tiến sĩ Weinhaus! Đối với bất kỳ ai không biết anh ta là ai, anh ta đã viết một số nghiên cứu quan trọng về đồ họa máy tính bắt đầu từ những năm 1970. Mọi người nên kiểm tra tầm nhìn tuyệt vời của mình về các tập lệnh shell ImageMagick tại fmwconcept.com/imagemagick .
hackerb9

1
@ hackerb9: Vâng, đó là tôi. Chúng ta có biết nhau không? Gửi cho tôi một email nếu bạn muốn. Địa chỉ email của tôi nằm trên trang web mà bạn đã liên kết.
fmw42

4

Nếu bạn muốn kiểm soát mức độ minh bạch, bạn có thể sử dụng rgba. trong đó a là alpha. 0 cho trong suốt và 1 cho mờ đục. Đảm bảo rằng tệp đầu ra cuối cùng phải có phần mở rộng .png để minh bạch.

convert 
  test.png 
    -channel rgba 
    -matte 
    -fuzz 40% 
    -fill "rgba(255,255,255,0.5)" 
    -opaque "rgb(255,255,255)" 
       semi_transparent.png

1

Vâng. Cũng có vấn đề này. Đây là lệnh tôi đã chạy và nó hoạt động hoàn hảo: convert transparent-img1.png transparent-img2.png transparent-img3.png -channel Alpha favicon.ico

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.