#c# #visual-studio #jpeg
#c# #visual-studio #jpeg
Вопрос:
Я пытаюсь сохранить файл BITMAP для записи и убедиться, что результирующий файл меньше определенного размера. Мой код выглядит следующим образом
//Fetch Image from file
BitmapImage bitmap = new BitmapImage(new Uri("YourImage.jpg", UriKind.Relative));
WriteableBitmap writableBitmapImage = new WriteableBitmap(bitmap);
//initialize variables and values
MemoryStream stream;
JpegBitmapEncoder encoder;
byte[] resu<
int quality = 100;
//loop through save process, checking file size and changing quality
while (selected.maxFileSize < result.Length amp;amp; quality > 1)
{
encoder = new JpegBitmapEncoder();
stream = new MemoryStream();
encoder.QualityLevel = quality;
encoder.Frames.Add(BitmapFrame.Create(
ReplaceTransparency(writableBitmapImage, Colors.White))
);
encoder.Save(stream);
result = stream.GetBuffer();
if (quality > 5) quality = -5;
else quality--;
}
Когда я запускаю этот код, я не вижу никаких изменений размера файла от начальной точки QualityLevel = 100;
до QualityLevel = 10;
.
На QualityLevel = 5;
я вижу значительное изменение размера файла.
Есть ли какой-либо способ контролировать размер файла более детально?
Комментарии:
1. Хм, ты же на самом деле не пишешь белый прямоугольник, не так ли?
2. Почему вы создаете и настраиваете
encoder
только для того, чтобы выбросить это? Вы никогда не пишете наQualityLevel == 100
в своем примере кода. Кроме того, что находится вwritableBitmapImage
?3. @TaW Вы правы, я не пишу белый прямоугольник. Записываемый BitmapImage — это существующее записываемое BITMAP-изображение. Я не был уверен, как представить это в вопросе.
4. @NetMage Я настраиваю кодировщик, только для удаления, чтобы я мог установить encoder.QualityLevel перед входом в цикл while. Записываемый BitmapImage содержит существующее изображение, обычно снимок головы или портрет. Я не был уверен, что лучший способ показать это в коде. Мне пришлось сконструировать приведенный выше код из гораздо более крупной программы.
5. @NetMage Я отредактировал код для наглядности
Ответ №1:
Прочитайте документацию для MemoryStream.GetBuffer()
:
Обратите внимание, что буфер содержит выделенные байты, которые могут быть неиспользуемыми. Например, если строка «test» записывается в объект MemoryStream, длина буфера, возвращаемого из GetBuffer, равна 256, а не 4, при этом 252 байта не используются. Чтобы получить только данные в буфере, используйте метод toArray; однако toArray создает копию данных в памяти.
Тогда используйте .ToArray()
вместо этого.
Комментарии:
1. Или просто используйте
MemoryStream.Length
для определения фактической длины.