Форум программистов, компьютерный форум, киберфорум
Delphi: Графика, звук, видео
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
3420 / 1607 / 236
Регистрация: 26.02.2009
Сообщений: 7,858
Записей в блоге: 5
1

Сохранить PNG как grayscale 16bit

04.02.2013, 16:24. Показов 3381. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет!

Собственно сабж.
Из доки вычитал что для чтения 16bit нужно использовать ExtraScanline. Причём в Scanline хранится только первые 8bit данных, а старшие в ExtraScanline.

Проверил. Чтение вроде работает. А запись - нет!

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// var pLo, pHi:pByteArray;
// сохранил файл png через photoshop (grayscale; 16bit/channel)
png.LoadFromFile('C:\test.png');
for i:=0 to png.Height-1 do
begin
  pLo := png.ScanLine[i];
  pHi := png.ExtraScanline[i];
  for j:=0 to png.Width-1 do
    w := pLo[j] or pHi[j] shl 8; // вроде читает
  //в pHi[j] не нули 
end;
 
// теперь пытаюсь записать свои данные
for i:=0 to png.Height-1 do
begin
  pLo := png.ScanLine[i];
  pHi := png.ExtraScanline[i];
  for j:=0 to png.Width-1 do
    pHi[j] := j;// записываю свои данные( не нули )
end;
png.SaveToFile('C:\test.png'); // сохраняю
 
png.LoadFromFile('C:\test.png');
for i:=0 to png.Height-1 do // попытаюсь прочитать записанное
begin
  pLo := png.ScanLine[i];
  pHi := png.ExtraScanline[i];
  for j:=0 to png.Width-1 do
     //в pHi[j] ВСЕ не нули !!
end;
Что я делаю не так?

Добавлено через 2 минуты
http://docwiki.embarcadero.com... raScanline
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.02.2013, 16:24
Ответы с готовыми решениями:

Как содержимое TPaintBox сохранить в .png файл
Доброго времени суток. Мне нужно сохранить содержимое PaintBox в .png файлом с альфа слоем. Знаю,...

Как сохранить содержимое CANVAS в .PNG
Добрый день! Нужно сохранить содержимое CANVAS в .PNG (на компьютер пользователя). Пробовал...

Создать png и сохранить как картинку
header ('Content-Type: image/png'); $im = @imagecreatetruecolor(300, 300) or die('Ошибка при...

Сохранить как .png в том числе "свободный фон"
Добрый вечер, Простой пример, есть в кореле такая кнопка после экспорта получается как...

17
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
04.02.2013, 18:12 2
Цитата Сообщение от snake32 Посмотреть сообщение
for j:=0 to png.Width-1 do pHi[j] := j;// записываю свои данные( не нули )
один нуль точно пишешь при j=0
0
3420 / 1607 / 236
Регистрация: 26.02.2009
Сообщений: 7,858
Записей в блоге: 5
04.02.2013, 18:34  [ТС] 3
Цитата Сообщение от mss Посмотреть сообщение
один нуль точно пишешь при j=0
Спасибо, Кэп! Но у меня ширина png = 256. Откуда ещё 255 нулей взялось?
в pHi[j] ВСЕ нули !! 0<=j<256
0
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
04.02.2013, 20:40 4
Ты уж определись как-нибудь)
То ли у тебя

Цитата Сообщение от snake32 Посмотреть сообщение
//в pHi[j] ВСЕ не нули !!
то ли

Цитата Сообщение от snake32 Посмотреть сообщение
Откуда ещё 255 нулей взялось?
в pHi[j] ВСЕ нули !!
0
3420 / 1607 / 236
Регистрация: 26.02.2009
Сообщений: 7,858
Записей в блоге: 5
04.02.2013, 21:58  [ТС] 5
Цитата Сообщение от mss Посмотреть сообщение
Ты уж определись как-нибудь)
да хоть при любом раскладе! Важно что не совпадает записанное и считанное.
Имеются хоть какие-нибудь соображения?
0
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
04.02.2013, 22:22 6
пока не имеются
0
angstrom
04.02.2013, 23:21 7
А почему файлы должны совпадать? Совпадать должны битовые карты, а вот как сохранится в png - кодек его знает.
3420 / 1607 / 236
Регистрация: 26.02.2009
Сообщений: 7,858
Записей в блоге: 5
04.02.2013, 23:26  [ТС] 8
Цитата Сообщение от angstrom Посмотреть сообщение
А почему файлы должны совпадать?
Кто говорит что файлы совпадают? Записываемые данные не сохраняются
0
angstrom
04.02.2013, 23:32 9
Скинь архив, поэкспериментировать.
3420 / 1607 / 236
Регистрация: 26.02.2009
Сообщений: 7,858
Записей в блоге: 5
05.02.2013, 03:23  [ТС] 10
Короче ковыряю исходники pngimage.pas
И что я вижу? Эти котопсы вообще никак не используют Extra-поле!
Если при чтение ещё читается(обратите внимание на формальный параметр Extra):
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{Copy grayscale images with 16 bits}
procedure TChunkIDAT.CopyNonInterlacedGrayscale16(
  Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pByte);
var
  I: Integer;
begin
  FOR I := 1 TO ImageWidth DO
  begin
    {Windows does not supports 16 bits for each pixel in grayscale}
    {mode, so reduce to 8}
    Dest^ := Src^; inc(Dest);
    {$IFDEF Store16bits}
    Extra^ := pByte(Src + 1)^; inc(Extra);// <- вот заветная строка чтения
    {$ENDIF}
 
    {Move to next pixel}
    inc(Src, 2);
  end {for I}
end;
То при записи поле Extra вообще никак и нигде не фигурирует!
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{Copy memory to encode grayscale images with 2 bytes for each sample}
procedure TChunkIDAT.EncodeNonInterlacedGrayscale16(Src, Dest, Trans: pByte);
var
  I: Integer;
begin
  FOR I := 1 TO ImageWidth DO
  begin
    //Now we copy from 1 byte for each sample stored to a 2 bytes (or 1 word)
    //for sample
    pWORD(Dest)^ := pByte(Src)^; inc(Dest, 2); // <-ёж твой свет что это такое?
    {Move to next pixel}
    inc(Src);
  end {for I}
end;
Замечательно! Тупо байт в ворд запихали! Не удивительно что старший байт у меня всегда 0

Самое печальное то чтобы исправить это мне необходимо будет переписать минимум 8шт объявления методов.

Добавлено через 2 часа 47 минут
Удалил все стандартные Vcl.Imaging.pngimage.dcu. Теперь не находит Vcl.Imaging.pngimage. Как сгенерить стандартные dcu? Build All, Make, Compile не помогает
0
angstrom
05.02.2013, 04:18 11
Скомпилировать не проблема (копируешь в любой другой каталог и собираешь), но вот размер и дата создания будут отличаться от оригинальных.
3420 / 1607 / 236
Регистрация: 26.02.2009
Сообщений: 7,858
Записей в блоге: 5
05.02.2013, 15:22  [ТС] 12
Цитата Сообщение от angstrom Посмотреть сообщение
копируешь в любой другой каталог и собираешь
Да. Как лёг спать сразу об этом подумал. Сейчас другим занимаюсь. Может быть позже выложу рабочий pngimage.pas. Думаю вообще переименовать этот модуль. А стандартный не использовать вообще.
Цитата Сообщение от angstrom Посмотреть сообщение
о вот размер и дата создания будут отличаться от оригинальных.
А что? за этим кроются очередные грабли в кустах?
0
angstrom
05.02.2013, 15:44 13
Дельфи очень не любит, когда дата dcu файлов отличается от остальных в сборке.
240 / 218 / 46
Регистрация: 17.04.2010
Сообщений: 526
06.02.2013, 19:31 14
Цитата Сообщение от snake32 Посмотреть сообщение
как же сохранить 16bit grayscale, через стандартный модуль pngimage
Могу предложить изврат... Формат PNG 16bit grayscale (запись которого не поддерживается в pngimage) и формат 8bit grayscale+alpha, фактически отличаются только заголовком. Создаем обычный 8bit grayscale+alpha, раскидываем младшую и старшую часть слова между изображением и альфой, записываем, после чего подправляем заголовок.
как-то так:
Код
var
  i: integer;
  scan: pByteArray;
  tmp1,tmp2: TMemoryStream;
begin
  tmp1:=TMemoryStream.Create;
  tmp2:=TMemoryStream.Create;
  with TPNGObject.CreateBlank(COLOR_GRAYSCALEALPHA,8,256,1) do begin
    scan:=Scanline[0];
    for i:=0 to 255 do scan[i]:=i;
    scan:=AlphaScanline[0];
    for i:=0 to 255 do scan[i]:=255-i;
    SaveToStream(tmp1);
    Free;
  end;
  with TPNGObject.CreateBlank(COLOR_GRAYSCALE,16,256,1) do begin
    SaveToStream(tmp2);
    Free;
  end;
  CopyMemory(Pointer(DWORD(tmp1.Memory)+16), Pointer(DWORD(tmp2.Memory)+16), 17);
  tmp1.SaveToFile('16bit.png');
  tmp1.Free;
  tmp2.Free;
По хорошему нужно доработать модуль pngimage, но на скорую руку можно так извратится =)
1
3420 / 1607 / 236
Регистрация: 26.02.2009
Сообщений: 7,858
Записей в блоге: 5
06.02.2013, 20:09  [ТС] 15
x128, Да хотелось бы именно через 16bit grayscale. Потому что, как мне кажется, сжатие будет лучше и адекватная картинка при просмотре стандартными средствами, которые обычно нормально сделаны и поддерживают все форматы PNG. Извратится можно и по другому: Создать обычный png с COLOR_RGB и записывать только например в R и G, а B оставить пустым.
Не дочитал:
Цитата Сообщение от x128 Посмотреть сообщение
после чего подправляем заголовок.
Интересный вариант. И это Работает? Всмысле, если потом загрузить этот подправленный png он адекватно везде отобразится?
0
240 / 218 / 46
Регистрация: 17.04.2010
Сообщений: 526
06.02.2013, 20:20 16
snake32, в итоге получится обычный 16bit grayscale, на сжатии или понимании его другими программами это не скажется. Собственно, пример который я привел, создает изображение 256х1 с переходом, я хотел убедиться, что все получится =)
1
Заблокирован
07.02.2013, 01:03 17
хм.. но в PNGImage.pas есть полная поддержка сжатия в этот формат, как и во все остальные. К чему тогда весь этот огород городить?
0
2 / 2 / 1
Регистрация: 21.04.2013
Сообщений: 14
21.04.2013, 18:52 18
snake32, ты решил этот вопрос? Если да, поделись пожалуйста решением
0
21.04.2013, 18:52
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.04.2013, 18:52
Помогаю со студенческими работами здесь

Нужно сохранить результат в png, a не в bmp
Вот мой код, сохраняющий рисунок(фиолетовый квадрат) в bmp#include &lt;string&gt; #include &lt;vector&gt;...

Можно ли сохранить файл .png в виде двоичного файла?
Привет! Подскажите, можно ли сохранить графический файл png, bmp, jpg в виде двоичного файла?...

Сохранить в файл png изображение из bufferimage с сохранением прозрачности
Здравствуйте уважаемые форумчане, думал что все просто но в итоге увы не так, при классическом...

Получить иконку в формате ico и сохранить ее в формате png
Здравствуйте. Мне нужно получить иконку в формате ico и сохранить ее в формате png. Использую...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru