Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / ASP.NET Новый топик    Ответить
 Узнать качество изображения формата JPG  [new]
moid
GDN Member

Откуда: GotDotNet.Ru
Сообщений: N/A
Каким образом можно узнать качество загружаемого jpg файла?

Дайте пример

Данное сообщение получено с GotDotNet.Ru
28 янв 08, 18:02    [5212737]     Ответить | Цитировать Сообщить модератору
 Re: Узнать качество изображения формата JPG  [new]
M234
Member

Откуда: Оттуда...
Сообщений: 22734
moid
Каким образом можно узнать качество загружаемого jpg файла?

Дайте пример


А что вы имеете ввиду говоря "качество"?
Разрешение и глубину цвета? - Узнать легко.
Или может степень компрессии JPEG в процентном выражении? - узнать вряд ли удастся если этой инфы нет в EXIF-данных.

Что конкретно?
28 янв 08, 19:12    [5213030]     Ответить | Цитировать Сообщить модератору
 Re: Узнать качество изображения формата JPG  [new]
moid
GDN Member

Откуда: GotDotNet.Ru
Сообщений: N/A
степень компрессии JPEG в процентном выражении.
узнать вряд ли удастся если этой инфы нет в EXIF-данных
К примеру программа FastStone ImageViewer всегда узнает компрессию картинки.

Данное сообщение получено с GotDotNet.Ru
29 янв 08, 10:13    [5214385]     Ответить | Цитировать Сообщить модератору
 Re: Узнать качество изображения формата JPG  [new]
M234
Member

Откуда: Оттуда...
Сообщений: 22734
moid
степень компрессии JPEG в процентном выражении.
узнать вряд ли удастся если этой инфы нет в EXIF-данных
К примеру программа FastStone ImageViewer всегда узнает компрессию картинки.


Скачал, посмотрел, проверил.
Какие то проценты действительно показывает, только это всяко не степень сжатия.
29 янв 08, 10:52    [5214646]     Ответить | Цитировать Сообщить модератору
 Re: Узнать качество изображения формата JPG  [new]
Нахлобуч
Member

Откуда: https://hglabhq.com
Сообщений: 3942
moid
К примеру программа FastStone ImageViewer всегда узнает компрессию картинки.

А это, случаем, не отношение произведения длины на ширину и на глубину цвета к фактическому размеру?
29 янв 08, 11:05    [5214755]     Ответить | Цитировать Сообщить модератору
 Re: Узнать качество изображения формата JPG  [new]
M234
Member

Откуда: Оттуда...
Сообщений: 22734
Нахлобуч
moid
К примеру программа FastStone ImageViewer всегда узнает компрессию картинки.

А это, случаем, не отношение произведения длины на ширину и на глубину цвета к фактическому размеру?


Что? Те проценты у FastStone ImageViewer? Вряд ли. Я взял картинку где FastStone ImageViewer показывал 54% и сохранил её(под другим именем) с бОльшим сжатием. Размер картинки уменьшился в 5 раз, а FastStone ImageViewer показывает всё те же 54%.
29 янв 08, 11:13    [5214807]     Ответить | Цитировать Сообщить модератору
 Re: Узнать качество изображения формата JPG  [new]
XXI
GDN Member

Откуда: GotDotNet.Ru
Сообщений: N/A
Если имеются в виду зеленые проценты наверху экрана, то это масштаб картинки.
Any fool can write code that a computer can understand. Good programmers write code that humans can understand. ~Martin Fowler


Данное сообщение получено с GotDotNet.Ru
29 янв 08, 11:47    [5215067]     Ответить | Цитировать Сообщить модератору
 Re: Узнать качество изображения формата JPG  [new]
moid
GDN Member

Откуда: GotDotNet.Ru
Сообщений: N/A
Пробовал достучаться через Image.PropertyItems, ничего вразумительного не добился.

Данное сообщение получено с GotDotNet.Ru
29 янв 08, 12:49    [5215552]     Ответить | Цитировать Сообщить модератору
 Re: Узнать качество изображения формата JPG  [new]
moid
GDN Member

Откуда: GotDotNet.Ru
Сообщений: N/A
M234

Скачал, посмотрел, проверил.
Какие то проценты действительно показывает, только это всяко не степень сжатия.


На чем основан такой вывод? Почему нет?

Данное сообщение получено с GotDotNet.Ru
29 янв 08, 13:06    [5215690]     Ответить | Цитировать Сообщить модератору
 Re: Узнать качество изображения формата JPG  [new]
moid
GDN Member

Откуда: GotDotNet.Ru
Сообщений: N/A
К примеру:

Сохраняю програмно с заданным качеством сжатия изображение.

Програмулина показывает правильное сжатие файла.

Данное сообщение получено с GotDotNet.Ru
29 янв 08, 13:13    [5215723]     Ответить | Цитировать Сообщить модератору
 Re: Узнать качество изображения формата JPG  [new]
M234
Member

Откуда: Оттуда...
Сообщений: 22734
moid
К примеру:

Сохраняю програмно с заданным качеством сжатия изображение.

Програмулина показывает правильное сжатие файла.


А где вы смотрите?
Впрочем вот вам MSDN в руки: http://support.microsoft.com/kb/324790/EN-US/

Ибо в писании сказано:

Retrieve the Quality Factor from a JPEG File
The quality factor is not stored directly in the JPEG file, so you cannot read the quality factor from the file. However, you can read the quantization tables from the JPEG file by using the PropertyItems property on the Image class. But even with the quantization tables, you cannot always determine a quality factor.

You might be able to determine the quality factor by comparing the quantization tables against the "standard" IJG-generated tables. However, because some applications may use custom tables, you will not always find a match. For more information about the quantization tables, see the "References" section.
30 янв 08, 15:24    [5222230]     Ответить | Цитировать Сообщить модератору
 Re: Узнать качество изображения формата JPG  [new]
XXI
GDN Member

Откуда: GotDotNet.Ru
Сообщений: N/A
Как уже M234 отметил, нельзя достоверно определить Quality Factor, если компрессия сделана не в соответствии со стандартными таблицами IJG. К тому же кто мешает пользователю ранее сжатый JPEG файл со сжатием 50% потом сохранить со сжатием 99%. Как говорится, цифры не соответствуют действительности. Если в случае с нестандартными таблицами можно получить результат отличающийся от стандартного +-15-20%, то в случае пересохранения все будет гораздо сложнее, и этому посвящено несколько статей IEEE. Я тут почитал исходники ImageMagick, и решил переделать на C# алгоритм определения компрессии. Как я уже говорил, точность +-15-20%, в зависимости от того, каким редактором сжимаем файл. Использовать просто:
JpegQualityDetector.GetQuality("имя файла"). Возвращает значение в диапазоне 1-100, если -1 - значит найти не смог. Проверок на ошибки нет, но их добавить несложно.

using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;

namespace Must.Imaging
{
public static class JpegQualityDetector
{
private static byte[] TryExtractDqtSegment(Stream stream)
{
stream.Seek(0, SeekOrigin.Begin);

byte[] header = new byte[2];
if (stream.Read(header, 0, 2) != 2)
return null;
if (header[0] != 0xFF || header[1] != 0xD8)
return null;

// Cycle reading of segments, until we find FFDB (DQT) segment
byte[] segmentHeader = new byte[2]; // Marker
byte[] segmentLength = new byte[2];

while (true)
{
if (stream.Read(segmentHeader, 0, 2) != 2)
return null;
if (stream.Read(segmentLength, 0, 2) != 2)
return null;

if (segmentHeader[0] != 0xFF) // every segment starts from FF
return null;

if (segmentHeader[1] == 0xDA) // SOS, no more headers
return null;

int length = segmentLength[0] TryExtractDqtTables(byte[] dqt)
{
int length = dqt.Length;

int index = 0;

List dqtTables = new List();

do
{
int Pq = dqt[index] >> 4;
int Tq = dqt[index] & 0x0F;
index++;
if (Pq == 0) // 8-bit Qk
{
int[] dqtTable = new int[64];
for (int i = 0; i < 64; i++, index++)
dqtTable[i] = dqt[index];
dqtTables.Add(dqtTable);
}
else // Pq = 1 - 16-bit Qk
{
int[] dqtTable = new int[64];
for (int i = 0; i < 64; i++, index += 2)
dqtTable[i] = dqt[index] < length);
return dqtTables;
}

public static int GetQuality(string fileName)
{
Stream str = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] dqt = TryExtractDqtSegment(str);
List dqtTables = TryExtractDqtTables(dqt);

int sum = 0;
foreach (int[] dqtTable in dqtTables)
foreach (int quant in dqtTable)
sum += quant;

int value = 0;

if (dqtTables.Count == 2)
{
int[] hash = new int[101]
{
1020, 1015, 932, 848, 780, 735, 702, 679, 660, 645,
632, 623, 613, 607, 600, 594, 589, 585, 581, 571,
555, 542, 529, 514, 494, 474, 457, 439, 424, 410,
397, 386, 373, 364, 351, 341, 334, 324, 317, 309,
299, 294, 287, 279, 274, 267, 262, 257, 251, 247,
243, 237, 232, 227, 222, 217, 213, 207, 202, 198,
192, 188, 183, 177, 173, 168, 163, 157, 153, 148,
143, 139, 132, 128, 125, 119, 115, 108, 104, 99,
94, 90, 84, 79, 74, 70, 64, 59, 55, 49,
45, 40, 34, 30, 25, 20, 15, 11, 6, 4,
0
};
int[] sums = new int[101]
{
32640, 32635, 32266, 31495, 30665, 29804, 29146, 28599, 28104,
27670, 27225, 26725, 26210, 25716, 25240, 24789, 24373, 23946,
23572, 22846, 21801, 20842, 19949, 19121, 18386, 17651, 16998,
16349, 15800, 15247, 14783, 14321, 13859, 13535, 13081, 12702,
12423, 12056, 11779, 11513, 11135, 10955, 10676, 10392, 10208,
9928, 9747, 9564, 9369, 9193, 9017, 8822, 8639, 8458,
8270, 8084, 7896, 7710, 7527, 7347, 7156, 6977, 6788,
6607, 6422, 6236, 6054, 5867, 5684, 5495, 5305, 5128,
4945, 4751, 4638, 4442, 4248, 4065, 3888, 3698, 3509,
3326, 3139, 2957, 2775, 2586, 2405, 2216, 2037, 1846,
1666, 1483, 1297, 1109, 927, 735, 554, 375, 201,
128, 0
};
value = dqtTables[0][2] + dqtTables[0][53] + dqtTables[1][0] + dqtTables[1][63];
for (int i = 0; i < 100; i++)
{
if ((value < hash[i]) && (sum < sums[i]))
continue;
return i + 1;
}
}
else if (dqtTables.Count == 1)
{
int[] hash = new int[101]
{
510, 505, 422, 380, 355, 338, 326, 318, 311, 305,
300, 297, 293, 291, 288, 286, 284, 283, 281, 280,
279, 278, 277, 273, 262, 251, 243, 233, 225, 218,
211, 205, 198, 193, 186, 181, 177, 172, 168, 164,
158, 156, 152, 148, 145, 142, 139, 136, 133, 131,
129, 126, 123, 120, 118, 115, 113, 110, 107, 105,
102, 100, 97, 94, 92, 89, 87, 83, 81, 79,
76, 74, 70, 68, 66, 63, 61, 57, 55, 52,
50, 48, 44, 42, 39, 37, 34, 31, 29, 26,
24, 21, 18, 16, 13, 11, 8, 6, 3, 2,
0
};
int[] sums = new int[101]
{
16320, 16315, 15946, 15277, 14655, 14073, 13623, 13230, 12859,
12560, 12240, 11861, 11456, 11081, 10714, 10360, 10027, 9679,
9368, 9056, 8680, 8331, 7995, 7668, 7376, 7084, 6823,
6562, 6345, 6125, 5939, 5756, 5571, 5421, 5240, 5086,
4976, 4829, 4719, 4616, 4463, 4393, 4280, 4166, 4092,
3980, 3909, 3835, 3755, 3688, 3621, 3541, 3467, 3396,
3323, 3247, 3170, 3096, 3021, 2952, 2874, 2804, 2727,
2657, 2583, 2509, 2437, 2362, 2290, 2211, 2136, 2068,
1996, 1915, 1858, 1773, 1692, 1620, 1552, 1477, 1398,
1326, 1251, 1179, 1109, 1031, 961, 884, 814, 736,
667, 592, 518, 441, 369, 292, 221, 151, 86,
64, 0
};
value = dqtTables[0][2] + dqtTables[0][53];
for (int i = 0; i < 100; i++)
{
if ((value < hash[i]) && (sum < sums[i]))
continue;
return i + 1;
}
}

return -1;

}
}
}
Any fool can write code that a computer can understand. Good programmers write code that humans can understand. ~Martin Fowler


Данное сообщение получено с GotDotNet.Ru
16 апр 08, 11:01    [5552857]     Ответить | Цитировать Сообщить модератору
Все форумы / ASP.NET Ответить