LINUX.ORG.RU

Ответ на: комментарий от ZenitharChampion

Судя по скриншоту, он именно в фреймбуфере и сидит.

cocucka ★★★★☆
()

У меня сомнения, что у тебя фреймбуфер запущен в режиме 640х480@16.

Попробуй 800х600@32.

cocucka ★★★★☆
()
Ответ на: комментарий от deep-purple

У меня RGB 666. Мне нужно 18 бит. Но их нет поэтому ставлю 16 бит.

Alex_Golubev
() автор топика
Ответ на: комментарий от Alex_Golubev

Проверь какое разрешение стоит cat /sys/class/graphics/fb0/virtual_size

Глубину цвета тоже где-то можно посмотреть. Она может быть и 8 бит. Вроде комманда была fbset -i, что-то вроде того.

cocucka ★★★★☆
()
Ответ на: комментарий от Alex_Golubev

Когда набираешь путь в консоли, можно набирать не польностью, а набрать только часть и нажать «Tab» (1 раз) — оно или само допишет или (второй раз если не дописало) предложит список, если путей с одинаковым префиксом больше одного.

deep-purple ★★★★★
()

Еще можешь попробовать cat /dev/fb0 > image.raw и открыть в GIMP как Raw image data. Придется поиграть с битностью и очередностью цветов.

cocucka ★★★★☆
()
Ответ на: комментарий от cocucka

Примерно такое делал dd if=/dev/fb0 of=screenshot.raw bs=1228800 count=1 все работает. Но почему fbgrab не работает?

Alex_Golubev
() автор топика
Ответ на: комментарий от Alex_Golubev

а вот теперь поиграйся с битностью, если опять вывалит «Not enough memory or data» — ещё уменьши размеры грабинга и продолжай играть.

deep-purple ★★★★★
()
Ответ на: комментарий от Alex_Golubev

Проблема, видимо, в несоответствии разрешения/глубины цвета/порядка цвета в фреймбуфере и в параметрах fbgrab.

Если в гимпе открывается нормально, то надо запомнить параметры и их передавать в fbgrab, если они ей поддерживаются, конечно.

У разных драйверов фреймбуфера могут быть разные способы кодирования данных в буфере. Надо доки смотреть. Тогда можно уже самому байты подвигать и в нормальный формат перегнать.

cocucka ★★★★☆
()
Ответ на: комментарий от cocucka

Ещё, с полосками у меня бывало когда рав-картинку читаешь не с тем кол-вом столбцов в строке, т.е. может оно даже читает или выдаёт в не правильное разрешение, кстати, об этом может намекать «/sys/class/graphics/fb0/virtual_size» — «virtual_size», тобишь виртуальный, а не реальный, на чём и спотыкается скриншотилка.

deep-purple ★★★★★
()
Ответ на: комментарий от Alex_Golubev

Так может тогда не перебирать все комбинации, а использовать то что работает?

dd if=/dev/fb0 of=screenshot.raw bs=1228800 count=1

deep-purple ★★★★★
()
Ответ на: комментарий от Alex_Golubev

А если без указания опций вообще, то что fbgrab выдает? Т.е. fbgrab test.png. И да, дисплей-то нормально изображение выводит?

cocucka ★★★★☆
()
Ответ на: комментарий от Alex_Golubev

Что еще можно попробовать? Как понять в чем проблема ?

Что за версия fbgrab? Посмотри исходники, чего гадать если можно это прямо проверить.

V1KT0P ★★
()
Ответ на: комментарий от cocucka

Пустой снимок выводит и все. Изображение нормальное.

Alex_Golubev
() автор топика
Ответ на: комментарий от Alex_Golubev

Версия fbgrab-1.3

Если это вот отсюда: https://fbgrab.monells.se/ То там действительно нет поддержки RGB666:

    switch(bits) 
    {
    case 15:
	convert1555to32(width, height, inbuffer, outbuffer);
	write_PNG(outbuffer, filename, width, height, interlace, compression);
	break;
    case 16:
	convert565to32(width, height, inbuffer, outbuffer);
	write_PNG(outbuffer, filename, width, height, interlace, compression);
	break;
    case 24:
	convert888to32(width, height, inbuffer, outbuffer);
	write_PNG(outbuffer, filename, width, height, interlace, compression);
	break;
    case 32:
	convert8888to32(width, height, inbuffer, outbuffer);
	write_PNG(outbuffer, filename, width, height, interlace, compression);
	break;
    default:
	fprintf(stderr, "%d bits per pixel are not supported! ", bits);
	exit(EXIT_FAILURE);
    }

Всего-то надо добавить вот это:

    case 18:
	convert666to32(width, height, inbuffer, outbuffer);
	write_PNG(outbuffer, filename, width, height, interlace, compression);

И реализовать саму функцию convert666to32, там где-то 10-20 строк всего будет.

Это если тебе подходит вариант патча fbgrab и сборки из исходников.

V1KT0P ★★
()
Ответ на: комментарий от V1KT0P

Сделал но не заработало. Мне кажется что нужно еще и править размеры w h.

[code] static void convert666to32(int width, int height, unsigned char *inbuffer, unsigned char *outbuffer) { unsigned int i;

for (i=0; i < (unsigned int) height*width*2; i+=2)
{
/* BLUE  = 0 */
outbuffer[(i<<1)+Blue] = (inbuffer[i] & 0x3f) << 2;
/* GREEN = 1 */
    outbuffer[(i<<1)+Green] = (((inbuffer[i+1] & 0xf) << 2) | 
		     (inbuffer[i] & 0xC0) >> 6) << 2;	
    /* RED   = 2 */
outbuffer[(i<<1)+Red] = (inbuffer[i+1] & 0xFC);
/* ALPHA = 3 */
outbuffer[(i<<1)+Alpha] = '\0'; 
}

}

static void convert_and_write(unsigned char *inbuffer, char *filename, int width, int height, int bits, int interlace, int compression) { size_t bufsize = (size_t) width * height * 4;

unsigned char *outbuffer = malloc(bufsize);

if (outbuffer == NULL)
fatal_error("Not enough memory");

memset(outbuffer, 0, bufsize);

fprintf(stderr, "Converting image from %i\n", bits);

switch(bits) 
{
case 15:
convert1555to32(width, height, inbuffer, outbuffer);
write_PNG(outbuffer, filename, width, height, interlace, compression);
break;
case 16:
convert565to32(width, height, inbuffer, outbuffer);
write_PNG(outbuffer, filename, width, height, interlace, compression);
break;
case 18:
    convert666to32(width, height, inbuffer, outbuffer);
    write_PNG(outbuffer, filename, width, height, interlace, compression);
    break;
case 24:
convert888to32(width, height, inbuffer, outbuffer);
write_PNG(outbuffer, filename, width, height, interlace, compression);
break;
case 32:
convert8888to32(width, height, inbuffer, outbuffer);
write_PNG(outbuffer, filename, width, height, interlace, compression);
break;
default:
fprintf(stderr, "%d bits per pixel are not supported! ", bits);
exit(EXIT_FAILURE);
}
    
(void) free(outbuffer);

}

[/code]

Alex_Golubev
() автор топика
Ответ на: комментарий от Alex_Golubev

Сделал но не заработало. Мне кажется что нужно еще и править размеры w h.

Что то я не понял по какому принципу ты сделал convert666to32, у тебя получается итерация каждые 2 байта, но у 18бит итерация в таком случае должны быть 2 байта и 2 бита.

Попробуй вот такой вариант, если я не ошибся должно работать(если цвета будут не те, то возможно надо Blue и Red местами поменять):

static void convert666to32(int width, int height, unsigned char *inbuffer, unsigned char *outbuffer)
{
    unsigned int i;
    for (i = 0; i < (unsigned int) height*width; ++i) {
        unsigned int offset = (i * 18) / 8;
        unsigned int temp = (inbuffer[offset] << 16 | inbuffer[offset + 1] << 8 | inbuffer[offset + 2]) << ((i & 0x03) * 2);
        /* BLUE  = 0 */
        outbuffer[(i << 2) + Blue] = (temp & 0xFC0000 ) >> 18;
        /* GREEN = 1 */
        outbuffer[(i << 2) + Green] = (temp & 0x03F000 ) >> 12;
        /* RED   = 2 */
        outbuffer[(i << 2) + Red] = (temp & 0x000FC0 ) >> 6;
        /* ALPHA */
        outbuffer[(i << 2) + Alpha] = '\0';
    }
}

V1KT0P ★★
()
Ответ на: комментарий от V1KT0P

Не заработало. Куда еще можно копать? Если сделать dd if=/dev/fb0 of=screenshot.raw bs=1228800 count=1 Потом в gimp открыть с настройками Raw image data -> ARGB 640x480 То все нормально.

Alex_Golubev
() автор топика
Последнее исправление: Alex_Golubev (всего исправлений: 1)
Ответ на: комментарий от Alex_Golubev

Не заработало. Куда еще можно копать?

Выложи куда-нибудь пример screenshot.raw.

dd if=/dev/fb0 of=screenshot.raw bs=1228800 count=1

Чтоб можно было глянуть что там действительно находится и в каком виде. Так проще будет чем гадать.

V1KT0P ★★
()
Ответ на: комментарий от Alex_Golubev

Если сделать dd if=/dev/fb0 of=screenshot.raw bs=1228800 count=1 Потом в gimp открыть с настройками Raw image data -> ARGB 640x480 То все нормально

640x480x32 будет ровно 1228800. Может у тебя там просто 32бита?

Что-то из этого работает?

fbgrab -w 640 -h 480 -b 32 32bit.png
fbgrab -w 640 -h 480 -b 24 24bit.png
V1KT0P ★★
()
Ответ на: комментарий от Alex_Golubev

Выдает пустые картинки на fbgrab -w 640 -h 480 -b 32 32bit.png

Выложи вот эту 32bit.png.

V1KT0P ★★
()
Ответ на: комментарий от Alex_Golubev

Попробуй как вот эти две команды(первая должна по идеи работать):

fbgrab -v -dev /dev/fb0 -w 640 -h 480 -b 32 fb0.png
fbgrab -v -w 640 -h 480 -b 32 default.png

И выводы обеих команд покажи.

V1KT0P ★★
()
Последнее исправление: V1KT0P (всего исправлений: 1)
Ответ на: комментарий от V1KT0P

Вот ссылки на картинки https://yadi.sk/i/Aqa5LEBgie3oOw https://yadi.sk/i/O3vVWdYcQEMdug На команду fbgrab -v -dev /dev/fb0 -w 640 -h 480 -b 32 fb0.png

Выдает следующие

fbgrab -v -dev /dev/fb0 -w 640 -h 480 -b 32 fb0.png

Usage: fbgrab [-hi] [-{C|c} vt] [-d dev] [-s n] [-z n] [-f fromfile -w n -h n -b n] filename.png

Alex_Golubev
() автор топика
Ответ на: комментарий от V1KT0P

применение команды:

[list]

fbgrab -v -d /dev/fb0 -w 640 -h 480 -b 32 fb0.png

frame buffer fixed info: id: «DRM emulated» type: packed pixels line length: 2560 bytes (640 pixels)

frame buffer variable info: resolution: 640x480 virtual resolution: 640x480 offset: 0x0 bits_per_pixel: 32 grayscale: false red: offset: 16, length: 8, msb_right: 0 green: offset: 8, length: 8, msb_right: 0 blue: offset: 0, length: 8, msb_right: 0 alpha: offset: 0, length: 0, msb_right: 0 pixel format: standard Resolution: 640x480 depth 32 Converting image from 32 Now writing PNG file (compression -1) [/list]

Результат пустая картинка. https://yadi.sk/i/CKo7OFYJFi9xEQ

Alex_Golubev
() автор топика
Последнее исправление: Alex_Golubev (всего исправлений: 4)
Ответ на: комментарий от Alex_Golubev

Результат пустая картинка.

Картинка не пустая это уже по размеру файла видно, там что-то не так с альфа каналом. Вся картинка полностью прозрачная, хотя должно быть наоборот.

V1KT0P ★★
()
Ответ на: комментарий от Alex_Golubev

Блин я понял. Согласно исходникам fbgrab полностью непрозрачный альфа канал это 0x00. Хотя по идеи должен быть 0xFF, что и возращает framebuffer.

Замени вот эту строку:

outbuffer[(i<<2)+Alpha] = srcAlpha >= 0 ? inbuffer[i*4+srcAlpha] : 0xff;

на вот эту:

outbuffer[(i<<2)+Alpha] = '\0';

Должно заработать.

Да, fbgrab инвертирует значение альфы:

png_set_invert_alpha(png_ptr);

По хорошему надо определять надо ли инвертировать или не надо, плюс добавить опцию для принудительной установки инверсии.

V1KT0P ★★
()
Последнее исправление: V1KT0P (всего исправлений: 2)
Ответ на: комментарий от bormant

Можно строчку с outbuffer[] оставить в покое, закомментировав

Тогда для других режимов надо менять:

outbuffer[(i<<1)+Alpha] = '\0'; 

на:

outbuffer[(i<<1)+Alpha] = 0xFF; 

А то переключится из 32bit на 24bit и снова не будет изображения.

V1KT0P ★★
()
Ответ на: комментарий от V1KT0P

Все работает. Проблема найдена. Нужно наверное как-то добавить ключ или еще что. Чтобы как-то автоматизировать процесс.

Alex_Golubev
() автор топика
Ответ на: комментарий от V1KT0P

Хм, это еще бабка надвое сказала, нужно проверять, как оно в тех режимах работает...

А вот для варианта

alpha: offset: 0, length: 0, msb_right: 0
т.е. нет альфаканала, srcAlpha == -1, и с учетом инверсии, должно было быть:
    outbuffer[(i<<2)+Alpha] = srcAlpha >= 0 ? inbuffer[i*4+srcAlpha] : 0;

то есть
-    outbuffer[(i<<2)+Alpha] = srcAlpha >= 0 ? inbuffer[i*4+srcAlpha] : 0xff;
+    outbuffer[(i<<2)+Alpha] = srcAlpha >= 0 ? inbuffer[i*4+srcAlpha] : 0;


PS. Можно не проверять ;-) Если там альфаканал перманентно 0, то и тут при его отсутствии должен быть 0, а не 0xff.

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 3)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.