Tôi đang cố tải hình ảnh PNG bằng SDL nhưng chương trình không hoạt động và lỗi này xuất hiện trong bảng điều khiển
cảnh báo libpng: iCCP: biết hồ sơ sRGB không chính xác
Tại sao cảnh báo này xuất hiện? Tôi nên làm gì để giải quyết vấn đề này?
Tôi đang cố tải hình ảnh PNG bằng SDL nhưng chương trình không hoạt động và lỗi này xuất hiện trong bảng điều khiển
cảnh báo libpng: iCCP: biết hồ sơ sRGB không chính xác
Tại sao cảnh báo này xuất hiện? Tôi nên làm gì để giải quyết vấn đề này?
Câu trả lời:
Libpng-1.6 nghiêm ngặt hơn trong việc kiểm tra hồ sơ ICC so với các phiên bản trước. Bạn có thể bỏ qua cảnh báo. Để loại bỏ nó, hãy xóa đoạn iCCP khỏi hình ảnh PNG.
Một số ứng dụng coi cảnh báo là lỗi; nếu bạn đang sử dụng một ứng dụng như vậy, bạn phải loại bỏ đoạn này. Bạn có thể làm điều đó với bất kỳ trình chỉnh sửa PNG nào như ImageMagick's
convert in.png out.png
Để xóa đoạn iCCP không hợp lệ khỏi tất cả các tệp PNG trong một thư mục (thư mục), bạn có thể sử dụng mogrify
từ ImageMagick:
mogrify *.png
Điều này đòi hỏi ImageMagick của bạn được xây dựng với libpng16. Bạn có thể dễ dàng kiểm tra nó bằng cách chạy:
convert -list format | grep PNG
Nếu bạn muốn tìm ra những tập tin nào cần được sửa chữa thay vì xử lý một cách mù quáng tất cả chúng, bạn có thể chạy
pngcrush -n -q *.png
trong đó -n
phương tiện không ghi lại các tệp và -q
có nghĩa là triệt tiêu hầu hết đầu ra ngoại trừ các cảnh báo. Xin lỗi, không có tùy chọn nào trong pngcrush để đàn áp mọi thứ trừ các cảnh báo.
Các bản phát hành nhị phân của ImageMagick đang ở đây
Đối với Dự án Android (Android Studio) điều hướng vào res
thư mục.
Ví dụ:
C:\{your_project_folder}\app\src\main\res\drawable-hdpi\mogrify *.png
mogrify **/*.png
dường như sửa đổi tất cả các tập tin trong cây. Tôi chỉ muốn cập nhật một hình ảnh bị lỗi.
find . -type f -name '*.png' -execute mogrify \{\} \;
để sửa đổi đệ quy .png
các tập tin trong thư mục hiện tại.
-ow
ghi đè và sửa tệp và cũng giảm kích thước khoảng 1/6! Chỉ cần lấy mã nguồn của chương trình cho máy mac của tôi, biên dịch, cài đặt thủ công và chạy nó. GitHub Kjuly / pngcrush có thể có một nhị phân được biên dịch sẵn, nhưng không chắc chắn. Sourceforge dường như chỉ có sẵn exe của Windows và mã nguồn. Câu trả lời của Friederbluemle dường như làm điều này và hơn thế nữa.
Sử dụng pngcrush
để xóa hồ sơ sRGB không chính xác khỏi tệp png:
pngcrush -ow -rem allb -reduce file.png
-ow
sẽ ghi đè lên tập tin đầu vào-rem allb
sẽ loại bỏ tất cả các phần phụ trợ trừ tRNS và gAMA-reduce
không loại màu không mất hoặc giảm độ sâu bitTrong đầu ra giao diện điều khiển, bạn sẽ thấy Removed the sRGB chunk
và có thể có nhiều thông báo hơn về việc loại bỏ khối. Bạn sẽ kết thúc với một tệp PNG nhỏ hơn, được tối ưu hóa. Vì lệnh sẽ ghi đè lên tệp gốc, hãy đảm bảo tạo bản sao lưu hoặc sử dụng kiểm soát phiên bản.
find . -type f -iname '*.png' -exec pngcrush -ow -rem allb -reduce {} \;
(Đã thử nghiệm trên GNU / Linux)
Hồ sơ không chính xác có thể được sửa bởi:
Lưu ý: Giải pháp này sử dụng Thư viện Qt .
Dưới đây là một ví dụ tối thiểu tôi đã viết bằng C ++ để trình bày cách triển khai giải pháp đề xuất:
QPixmap pixmap;
pixmap.load("badProfileImage.png");
QFile file("goodProfileImage.png");
file.open(QIODevice::WriteOnly);
pixmap.save(&file, "PNG");
Mã nguồn hoàn chỉnh của ứng dụng GUI dựa trên ví dụ này có sẵn trên GitHub .
CẬP NHẬT TỪ NGÀY 05.12.2019: Câu trả lời đã và vẫn còn hiệu lực, tuy nhiên có một lỗi trong ứng dụng GUI tôi đã chia sẻ trên GitHub, khiến hình ảnh đầu ra bị trống. Tôi vừa sửa nó và xin lỗi vì sự bất tiện này!
Bạn cũng có thể sửa lỗi này trong photoshop ...
Để thêm vào câu trả lời tuyệt vời của Glenn, đây là những gì tôi đã làm để tìm tệp nào bị lỗi:
find . -name "*.png" -type f -print0 | xargs \
-0 pngcrush_1_8_8_w64.exe -n -q > pngError.txt 2>&1
Tôi đã sử dụng find và xargs vì pngcrush không thể xử lý nhiều đối số (được trả về bởi **/*.png
). Các -print0
và -0
được yêu cầu để xử lý tên tập tin chứa khoảng trắng.
Sau đó tìm kiếm trong đầu ra cho các dòng này : iCCP: Not recognizing known sRGB profile that has been edited
.
./Installer/Images/installer_background.png:
Total length of data found in critical chunks = 11286
pngcrush: iCCP: Not recognizing known sRGB profile that has been edited
Và đối với mỗi người trong số họ, hãy chạy mogrify trên nó để sửa chúng.
mogrify ./Installer/Images/installer_background.png
Làm điều này ngăn chặn việc cam kết thay đổi mọi tệp png duy nhất trong kho lưu trữ khi chỉ một số ít thực sự được sửa đổi. Thêm vào đó, nó có lợi thế để hiển thị chính xác các tập tin bị lỗi.
Tôi đã thử nghiệm điều này trên Windows với bảng điều khiển Cygwin và vỏ zsh. Một lần nữa xin cảm ơn Glenn , người đã đưa ra hầu hết những điều trên, tôi chỉ thêm một câu trả lời vì nó thường dễ tìm hơn bình luận :)
find . -name "*.png" -exec sh -c 'echo Testing {} && pngcrush -n -q {}' \;
Mọi PNG bị lỗi sẽ tạo rapngcrush: iCCP: known incorrect sRGB profile
Nhờ câu trả lời tuyệt vời từ Glenn , tôi đã sử dụng chức năng "mogrify * .png" của ImageMagik . Tuy nhiên, tôi đã có hình ảnh được chôn trong các thư mục con, vì vậy tôi đã sử dụng tập lệnh Python đơn giản này để áp dụng điều này cho tất cả các hình ảnh trong tất cả các thư mục phụ và nghĩ rằng nó có thể giúp người khác:
import os
import subprocess
def system_call(args, cwd="."):
print("Running '{}' in '{}'".format(str(args), cwd))
subprocess.call(args, cwd=cwd)
pass
def fix_image_files(root=os.curdir):
for path, dirs, files in os.walk(os.path.abspath(root)):
# sys.stdout.write('.')
for dir in dirs:
system_call("mogrify *.png", "{}".format(os.path.join(path, dir)))
fix_image_files(os.curdir)
mogrify **/*.png
.
Có một cách dễ dàng hơn để khắc phục sự cố này với Mac OS và Homebrew:
Cài đặt homebrew nếu nó chưa được cài đặt
$brew install libpng
$pngfix --strip=color --out=file2.png file.png
hoặc để làm điều đó với mọi tệp trong thư mục hiện tại:
mkdir tmp; for f in ./*.png; do pngfix --strip=color --out=tmp/"$f" "$f"; done
Nó sẽ tạo một bản sao cố định cho mỗi tệp png trong thư mục hiện tại và đặt nó trong thư mục con tmp. Sau đó, nếu mọi thứ đều ổn, bạn chỉ cần ghi đè lên các tệp gốc.
Một mẹo khác là sử dụng các ứng dụng Keynote và Preview để tạo các biểu tượng. Tôi vẽ chúng bằng Keynote, với kích thước khoảng 120x120 pixel, trên một slide có nền trắng (tùy chọn để tạo đa giác có thể chỉnh sửa là tuyệt vời!). Trước khi xuất sang Xem trước, tôi vẽ một hình chữ nhật xung quanh biểu tượng (không có bất kỳ hình tô hoặc bóng nào, chỉ là đường viền, với kích thước khoảng 135x135) và sao chép mọi thứ vào bảng tạm. Sau đó, bạn chỉ cần mở nó bằng công cụ Xem trước bằng cách sử dụng "Mới từ Clipboard", chọn vùng 128x128 pixel xung quanh biểu tượng, sao chép, sử dụng lại "Mới từ Clipboard" và xuất nó sang PNG. Bạn sẽ không cần chạy công cụ pngfix.
Sau khi thử một vài gợi ý trên trang này, tôi đã kết thúc bằng cách sử dụng giải pháp pngcrush. Bạn có thể sử dụng tập lệnh bash bên dưới để phát hiện đệ quy và sửa các cấu hình png xấu. Chỉ cần truyền cho nó đường dẫn đầy đủ đến thư mục bạn muốn tìm kiếm tệp png.
fixpng "/path/to/png/folder"
Kịch bản:
#!/bin/bash
FILES=$(find "$1" -type f -iname '*.png')
FIXED=0
for f in $FILES; do
WARN=$(pngcrush -n -warn "$f" 2>&1)
if [[ "$WARN" == *"PCS illuminant is not D50"* ]] || [[ "$WARN" == *"known incorrect sRGB profile"* ]]; then
pngcrush -s -ow -rem allb -reduce "$f"
FIXED=$((FIXED + 1))
fi
done
echo "$FIXED errors fixed"
pngcrush 1.7.85, uses libpng 1.6.21 and zlib 1.2.8
nhưng pngcrush của tôi không có -warn
cũng không -reduce
cờ vì vậy giải pháp này không hoạt động.
Một số thông tin cơ bản về điều này:
Một số thay đổi trong phiên bản libpng 1.6+ khiến nó đưa ra cảnh báo hoặc thậm chí không hoạt động chính xác với cấu hình sRGB HP / MS ban đầu, dẫn đến cảnh báo stderr: libpng sau: iCCP: hồ sơ sRGB không chính xác Cấu hình cũ sử dụng bảng trắng D50, trong đó D65 là tiêu chuẩn. Cấu hình này không phải là hiếm, đang được Adobe Photoshop sử dụng, mặc dù nó không được nhúng vào hình ảnh theo mặc định.
(nguồn: https://wiki.archlinux.org/index.php/Libpng_errors )
Phát hiện lỗi trong một số khối đã được cải thiện; đặc biệt là trình đọc đoạn mã iCCP hiện xác thực khá đầy đủ định dạng cơ bản. Một số cấu hình xấu đã được chấp nhận trước đây hiện bị từ chối, đặc biệt là cấu hình sRGB Microsoft / HP đã bị hỏng rất cũ. Yêu cầu thông số kỹ thuật PNG chỉ các cấu hình thang độ xám có thể xuất hiện trong các hình ảnh có loại màu 0 hoặc 4 và ngay cả khi hình ảnh chỉ chứa các pixel màu xám, chỉ các cấu hình RGB có thể xuất hiện trong các hình ảnh có loại màu 2, 3 hoặc 6, hiện được thi hành. Đoạn sRGB được phép xuất hiện trong ảnh với bất kỳ loại màu nào.
Mở rộng giải pháp Friederbluemle, tải xuống pngcrush và sau đó sử dụng mã như thế này nếu bạn đang chạy nó trên nhiều tệp png
path =r"C:\\project\\project\\images" # path to all .png images
import os
png_files =[]
for dirpath, subdirs, files in os.walk(path):
for x in files:
if x.endswith(".png"):
png_files.append(os.path.join(dirpath, x))
file =r'C:\\Users\\user\\Downloads\\pngcrush_1_8_9_w64.exe' #pngcrush file
for name in png_files:
cmd = r'{} -ow -rem allb -reduce {}'.format(file,name)
os.system(cmd)
ở đây tất cả các tệp png liên quan đến các dự án đều nằm trong 1 thư mục.
Tôi đã chạy hai lệnh đó trong thư mục gốc của dự án và nó đã được sửa.
Về cơ bản chuyển hướng đầu ra của lệnh "find" sang tệp văn bản để sử dụng làm danh sách các tệp của bạn để xử lý. Sau đó, bạn có thể đọc tệp văn bản đó thành "mogrify" bằng cách sử dụng cờ "@":
tìm * .png -mtime -1> list.txt
mogrify -resize 50% @ list.txt
Điều đó sẽ sử dụng "find" để có được tất cả các hình ảnh * .png mới hơn 1 ngày và in chúng thành một tệp có tên "list.txt". Sau đó, "mogrify" đọc danh sách đó, xử lý hình ảnh và ghi đè lên bản gốc bằng các phiên bản đã thay đổi kích thước. Có thể có sự khác biệt nhỏ trong hành vi "tìm" từ hệ thống này sang hệ thống khác, vì vậy bạn sẽ phải kiểm tra trang man để biết cách sử dụng chính xác.