.NET C#라이브러리에 대한 무손실 Exif 다시 쓰기?[마감]
문제
내가 찾는 다양한 코드와 라이브러리를 편집 Exif.
하지만 그들은 무손실 때 이미지의 너비와 높이입니다 여러 개의 16.
내가 찾는 것은 라이브러리(또는 그것을 할 수있는 방법 나)편집 다만 Exif 부분에 JPEG 파일(또는 추가 Exif 데이터가 존재하지 않는 경우 아직),을 떠나 다른 데이터 수정되지 않습니다.지 않는 가능한가요?
지금까지할 수 있었을 찾 Exif 부분(시작 0xFFE1)그러나 내가 이해하지 못하는 방법을 읽는 데이터입니다.
해결책
여기에는 사양에 대한 Exif interchange 형식을 계획하는 경우 코드에 당신의 자신의 라이브러리를 편집을 위한 태그가 있습니다.
http://www.exif.org/specifications.html
여기에 Perl 로 작성된 라이브러리는 귀하의 요구를 충족할 수 있는 것에서 배울 수 있:
http://www.sno.phy.queensu.ca/~필/exiftool/
여기에 괜찮은 있습니다.네트워크 라이브러리에 대한 Exif 평가 코드는 프로젝트:
다른 팁
지 않고 이 작업을 수행할 수 있습은 어떤 외부 lib:
// Create image.
Image image1 = Image.FromFile("c:\\Photo1.jpg");
// Get a PropertyItem from image1. Because PropertyItem does not
// have public constructor, you first need to get existing PropertyItem
PropertyItem propItem = image1.GetPropertyItem(20624);
// Change the ID of the PropertyItem.
propItem.Id = 20625;
// Set the new PropertyItem for image1.
image1.SetPropertyItem(propItem);
// Save the image.
image1.Save("c:\\Photo1.jpg", ImageFormat.Jpg);
목록 가능한 모든 PropertyItem id(exif)을 찾을 수 있습니다 기.
업데이트: 동의했고,이 방법이 다시 인코딩 이미지에 저장합니다.하지만 내가 기억하는 또 다른 방법에서,윈도 xp SP2 이상이 있는 새로운 영상 구성 요소를 추가-WIC,그리고 당신은 그들을 사용할 수 있습니다 무손실 쓰 metadate- 방법:다시코딩 JPEG 이미지와 메타데이터.
exiv2net 라이브러리(니다.NET 래퍼로의 상단에 exiv2)있을 수 있습니다 당신이 찾고 있습니다.
내가 쓴 작은 시험이 어디서 나 압축 파일 하나 많은 시간을 참조하여 품질 저하고 당신은 그것을 볼 수 있습에서 세 번째로 네 번째는 아주 나쁜 것입니다.
그러나 다행히도,당신은 항상 사용하여 동일한 QualityLevel 와 JpegBitmapEncoder 가입에 따른 수명저하 없음.
이 예에서 나는 다시 키워드를 100 배에서 메타데이터의 품질 보이지 않습니다.
private void LosslessJpegTest() {
var original = "d:\\!test\\TestInTest\\20150205_123011.jpg";
var copy = original;
const BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;
for (int i = 0; i < 100; i++) {
using (Stream originalFileStream = File.Open(copy, FileMode.Open, FileAccess.Read)) {
BitmapDecoder decoder = BitmapDecoder.Create(originalFileStream, createOptions, BitmapCacheOption.None);
if (decoder.CodecInfo == null || !decoder.CodecInfo.FileExtensions.Contains("jpg") || decoder.Frames[0] == null)
continue;
BitmapMetadata metadata = decoder.Frames[0].Metadata == null
? new BitmapMetadata("jpg")
: decoder.Frames[0].Metadata.Clone() as BitmapMetadata;
if (metadata == null) continue;
var keywords = metadata.Keywords == null ? new List<string>() : new List<string>(metadata.Keywords);
keywords.Add($"Keyword {i:000}");
metadata.Keywords = new ReadOnlyCollection<string>(keywords);
JpegBitmapEncoder encoder = new JpegBitmapEncoder {QualityLevel = 80};
encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0], decoder.Frames[0].Thumbnail, metadata,
decoder.Frames[0].ColorContexts));
copy = original.Replace(".", $"_{i:000}.");
using (Stream newFileStream = File.Open(copy, FileMode.Create, FileAccess.ReadWrite)) {
encoder.Save(newFileStream);
}
}
}
}