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).
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.
convert original.png -transparent white new.png
như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)?