Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 25.07.2020
Сообщений: 150

libjpeg проблемы с кодированием

20.09.2021, 22:22. Показов 2607. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет, я создал окно в который помещаю скрин экрана, не кодированные пиксели прорисовываются нормально однако когда я использую libjpeg, у меня получается страшная белиберда:

C++
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
bool JpegCompress(BYTE* buf, unsigned char **outbuffer, long unsigned int *outlen, int width, int height)
{
    struct jpeg_compress_struct cinfo = { 0 };
    struct jpeg_error_mgr jerr;
    JSAMPROW row_ptr[1];
    int row_stride;
 
    *outbuffer = NULL;
    *outlen = 0;
 
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_mem_dest(&cinfo, outbuffer, outlen);
 
    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;
 
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, 20, true);
    jpeg_start_compress(&cinfo, TRUE);
    row_stride = width * 3;
 
    while (cinfo.next_scanline < cinfo.image_height) {
        row_ptr[0] = &buf[cinfo.next_scanline * row_stride];
        jpeg_write_scanlines(&cinfo, row_ptr, 1);
    }
 
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
 
    return true;
}
 
bool JpegDecompress(unsigned char* inbuffer, unsigned char* &outbuffer, long unsigned int inlen)
{
    struct jpeg_decompress_struct cinfo = { 0 };
    struct jpeg_error_mgr jerr;
    unsigned char* rowptr[1];
    int data_size = 0;
 
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);
    jpeg_mem_src(&cinfo, inbuffer, inlen);
 
    if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK)
    {
        return false;
    }
    jpeg_start_decompress(&cinfo);
 
    outbuffer = (unsigned char*)malloc(cinfo.image_width * cinfo.image_height * 3);
 
    while (cinfo.output_scanline < cinfo.output_height)
    {
        rowptr[0] = &outbuffer[cinfo.output_scanline * cinfo.output_width * 3];
 
        jpeg_read_scanlines(&cinfo, rowptr, 1);
    }
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
 
    return true;
}
То есть я сначала скрин кодирую потом декодирую и копирую в окно. Почему такое плохое качество, я пробовал сжатие jpeg на 100 ставить, а там все равно черно белый скрин
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.09.2021, 22:22
Ответы с готовыми решениями:

Теория кодирования: какая разница между кодированием и L-кодированием?
какая разница между кодированием и L-кодированием?

Установка libjpeg
Не могу установить libjpeg на qt. Я находил некоторые способы установки, но они для linux. У меня win7 64b, help.

Прлблемы с libjpeg
1. Как им пользоваться? 2. Как установить? 3. Как скомпилировать .lib? Добавлено через 58 минут #include &lt;stdio.h&gt; ...

14
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
22.09.2021, 14:13
Я правильно понимаю, что вы создаёте HDC в памяти, затем помещаете на этот HDC изображение экрана?
Если так, то вам необходимо выбрать на HDC в памяти цветной BITMAP, потому что по умолчанию на HDC в памяти выбран чёрно‐белый BITMAP:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// HDC на основе HWND окна
HDC WindowDC = GetDC(hWin);
 
// HDC в памяти
HDC hMemoryDC = CreateCompatibleDC(WindowDC);
 
// Цветной Bitmap с шириной и высотой
HBITMAP ColorBitmap = CreateCompatibleBitmap(WindowDC, Width, Height);
 
// Освобождаем оконный HDC
ReleaseDC(hWin, WindowDC);
 
// выбираем цветной Bitmap в контекст в памяти
HBITMAP OldBitmap = SelectObject(hMemoryDC, ColorBitmap);
 
// Очистка:
SelectObject(hMemoryDC, OldBitmap);
DeleteObject(ColorBitmap);
DeleteDC(hMemoryDC);
0
0 / 0 / 0
Регистрация: 25.07.2020
Сообщений: 150
24.09.2021, 18:43  [ТС]
Замабувараев, я так и делаю, проблема не в кодере jpeg, а в изображении, т.к я попробовал сгенерировать rgb изображение и сжалось оно нормально. Вот как я делаю:
C++
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <windows.h>
#include <iostream>
#include "libjpeg/jpeglib.h"
 
int ScreenX = GetDeviceCaps(GetDC(0), HORZRES);
int ScreenY = GetDeviceCaps(GetDC(0), VERTRES);
 
BYTE* ScreenData = new BYTE[3 * ScreenX*ScreenY];
 
void ScreenCap()
{
    HDC hdc = GetDC(GetDesktopWindow());
    HDC hdcMem = CreateCompatibleDC(hdc);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdc, ScreenX, ScreenY);
    BITMAPINFOHEADER bmi = { 0 };
    bmi.biSize = sizeof(BITMAPINFOHEADER);
    bmi.biPlanes = 1;
    bmi.biBitCount = 24;
    bmi.biWidth = ScreenX;
    bmi.biHeight = -ScreenY;
    bmi.biCompression = BI_RGB;
    bmi.biSizeImage = ScreenX * ScreenY * 3;
    SelectObject(hdcMem, hBitmap);
    BitBlt(hdcMem, 0, 0, ScreenX, ScreenY, hdc, 0, 0, SRCCOPY);
    GetDIBits(hdc, hBitmap, 0, ScreenY, ScreenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
 
    DeleteDC(hdcMem);
    ReleaseDC(NULL, hdc);
}
 
size_t compress_rgb(unsigned char* in, unsigned char* out, int width, int height)
{
    struct jpeg_compress_struct cinfo = { 0 };
    struct jpeg_error_mgr jerr;
    JSAMPROW row_ptr[1];
    int row_stride;
    unsigned long int length = 0;
    unsigned char * output = NULL;
 
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_mem_dest(&cinfo, &output, &length);
 
    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;
 
    jpeg_set_defaults(&cinfo);
    jpeg_start_compress(&cinfo, TRUE);
    row_stride = width * 3;
    out = (BYTE*)malloc(width * height * 3);
 
    while (cinfo.next_scanline < cinfo.image_height) {
        row_ptr[0] = &in[cinfo.next_scanline * row_stride];
        jpeg_write_scanlines(&cinfo, row_ptr, 1);
    }
 
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
 
    DWORD rw;
    HANDLE Hfile;
    Hfile = CreateFileA("D:\\file.jpeg", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    WriteFile(Hfile, output, length, &rw, NULL);
    CloseHandle(Hfile);
    memcpy(out, output, length);
 
    return length;
}
 
int main()
{
    ScreenCap();
 
    BYTE* compressPixels = NULL;
 
    DWORD lencompressPixels = compress_rgb((BYTE*)ScreenData, compressPixels, ScreenX, ScreenY);
 
    Sleep(123122133);
}
Получается черно белое изображение с какими то цветовыми линиями

Добавлено через 4 часа 53 минуты
помоигте пожалуйста
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
25.09.2021, 20:20
Dhdbdb, ну во-первых, SelectObject(hdcMem, hBitmap); - где восстановление исходного состояния? Нужно либо обратно восстанавливать изображение через SelecObject либо использовать SaveDC/RestoreDC.

Во-вторых, размер буфера вычисляется неверно. Каждая строка пикселей должна быть выровнена на границу DWORD, вероятно в этом и проблема.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
25.09.2021, 21:24
Попробуйте сделать bmi.biBitCount = 32;
0
0 / 0 / 0
Регистрация: 25.07.2020
Сообщений: 150
26.09.2021, 10:25  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Во-вторых, размер буфера вычисляется неверно. Каждая строка пикселей должна быть выровнена на границу DWORD, вероятно в этом и проблема.
Всм? Я не понял, можете показать в каком месте ошибка?
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
26.09.2021, 20:44
Цитата Сообщение от Dhdbdb Посмотреть сообщение
Всм? Я не понял, можете показать в каком месте ошибка?
C
1
2
3
4
5
6
7
Stride = ((3 * ScreenX + 3) & -4);
...
ScreenData = new BYTE[Stride*ScreenY];
...
row_stride = Stride;
...
bmi.biSizeImage = Stride * ScreenY;
1
0 / 0 / 0
Регистрация: 25.07.2020
Сообщений: 150
27.09.2021, 19:00  [ТС]
The trick, спасибо, хоть что то начало вырисовываться:

Какие то непонятные потери в цветах
C++
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <windows.h>
#include <iostream>
#include "libjpeg/jpeglib.h"
 
int ScreenX = GetDeviceCaps(GetDC(0), HORZRES);
int ScreenY = GetDeviceCaps(GetDC(0), VERTRES);
 
BYTE* ScreenData = new BYTE[3 * ScreenX* ScreenY];
 
void ScreenCap()
{
    HDC hdc = GetDC(GetDesktopWindow());
    HDC hdcMem = CreateCompatibleDC(hdc);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdc, ScreenX, ScreenY);
    BITMAPINFOHEADER bmi = { 0 };
    bmi.biSize = sizeof(BITMAPINFOHEADER);
    bmi.biPlanes = 1;
    bmi.biBitCount = 24;
    bmi.biWidth = ScreenX;
    bmi.biHeight = -ScreenY;
    bmi.biCompression = BI_RGB;
    bmi.biSizeImage = ScreenX * ScreenY * 3;
    SelectObject(hdcMem, hBitmap);
    BitBlt(hdcMem, 0, 0, ScreenX, ScreenY, hdc, 0, 0, SRCCOPY);
    GetDIBits(hdc, hBitmap, 0, ScreenY, ScreenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
 
    DeleteDC(hdcMem);
    ReleaseDC(NULL, hdc);
}
 
size_t compress_rgb(unsigned char* in, unsigned char* out, int width, int height)
{
    struct jpeg_compress_struct cinfo = { 0 };
    struct jpeg_error_mgr jerr;
    JSAMPROW row_ptr[1];
    int row_stride;
    unsigned long int length = 0;
    int stride = 0;
    unsigned char * output = NULL;
 
    stride = ((3 * ScreenX + 3) & -4);
 
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_mem_dest(&cinfo, &output, &length);
 
    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;
 
    jpeg_set_defaults(&cinfo);
    jpeg_start_compress(&cinfo, TRUE);
    row_stride = stride;
 
    while (cinfo.next_scanline < cinfo.image_height) {
        row_ptr[0] = &in[cinfo.next_scanline * row_stride];
        jpeg_write_scanlines(&cinfo, row_ptr, 1);
    }
 
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
 
    DWORD rw;
    HANDLE Hfile;
    Hfile = CreateFileA("D:\\file.jpeg", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    WriteFile(Hfile, output, length, &rw, NULL);
    CloseHandle(Hfile);
 
    return length;
}
 
int main()
{
    Sleep(2000);
    ScreenCap();
 
    BYTE* compressPixels = NULL;
 
    DWORD lencompressPixels = compress_rgb((BYTE*)ScreenData, compressPixels, ScreenX, ScreenY);
 
    Sleep(123122133);
}
Изменил как вы и сказали
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
27.09.2021, 20:11
Цитата Сообщение от Dhdbdb Посмотреть сообщение
Какие то непонятные потери в цветах
Ну у тебя каналы R и B перепутаны - поменяй местами.

Цитата Сообщение от Dhdbdb Посмотреть сообщение
Изменил как вы и сказали
Неправильно, читай о чем я писал внимательно.
0
0 / 0 / 0
Регистрация: 25.07.2020
Сообщений: 150
27.09.2021, 22:39  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Неправильно, читай о чем я писал внимательно.
Цитата Сообщение от The trick Посмотреть сообщение
Dhdbdb, ну во-первых, SelectObject(hdcMem, hBitmap); - где восстановление исходного состояния? Нужно либо обратно восстанавливать изображение через SelecObject либо использовать SaveDC/RestoreDC.
Вот это вы имеете ввиду?
Цитата Сообщение от The trick Посмотреть сообщение
Stride = ((3 * ScreenX + 3) & -4);
...
ScreenData = new BYTE[Stride*ScreenY];
...
row_stride = Stride;
...
bmi.biSizeImage = Stride * ScreenY;
Или это? Тут всё нормально же
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
27.09.2021, 22:44
Размер буфера для пикселей высчитывается неверно, я написал как правильно считать. Во-вторых, не восстанавливается состояние DC и не удаляется битмап.
0
0 / 0 / 0
Регистрация: 25.07.2020
Сообщений: 150
27.09.2021, 23:03  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Размер буфера для пикселей высчитывается неверно, я написал как правильно считать
Да я реально не понимаю об чем вы. В каком месте не правильно высчитываю размер буфера?
Цитата Сообщение от Dhdbdb Посмотреть сообщение
BYTE* ScreenData = new BYTE[3 * ScreenX* ScreenY];
Тут? Да тут же по любому всё правльно
Цитата Сообщение от Dhdbdb Посмотреть сообщение
WriteFile(Hfile, output, length, &rw, NULL);
Или тут? У меня же length и будет размер получившегося буфера
Цитата Сообщение от Dhdbdb Посмотреть сообщение
stride = ((3 * ScreenX + 3) & -4);
Или здесь что то ни так? Я же сделал как вы показали
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
27.09.2021, 23:05
Цитата Сообщение от Dhdbdb Посмотреть сообщение
Тут? Да тут же по любому всё правльно
Да тут неверно.
0
0 / 0 / 0
Регистрация: 25.07.2020
Сообщений: 150
27.09.2021, 23:10  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Во-вторых, не восстанавливается состояние DC и не удаляется битмап.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void ScreenCap()
{
    HDC hdc = GetDC(GetDesktopWindow());
    HDC hdcMem = CreateCompatibleDC(hdc);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdc, ScreenX, ScreenY);
    BITMAPINFOHEADER bmi = { 0 };
    bmi.biSize = sizeof(BITMAPINFOHEADER);
    bmi.biPlanes = 1;
    bmi.biBitCount = 24;
    bmi.biWidth = ScreenX;
    bmi.biHeight = -ScreenY;
    bmi.biCompression = BI_RGB;
    bmi.biSizeImage = ScreenX * ScreenY * 3;
    SelectObject(hdcMem, hBitmap);
    BitBlt(hdcMem, 0, 0, ScreenX, ScreenY, hdc, 0, 0, SRCCOPY);
    GetDIBits(hdc, hBitmap, 0, ScreenY, ScreenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
 
    SelectObject(hdcMem, hBitmap);
DeleteObject(hBitmap);
    DeleteDC(hdcMem);
    ReleaseDC(NULL, hdc);
}
Надеюсь всё правильно сделал. На счет "во первых" я так и не понял
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
27.09.2021, 23:59
Цитата Сообщение от Dhdbdb Посмотреть сообщение
Надеюсь всё правильно сделал.
Неправильно. Изучи основы GDI и прочитай про функцию SelecObject, затем прочитай про BITMAPINFOHEADER.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.09.2021, 23:59
Помогаю со студенческими работами здесь

LibJpeg - как скомпилировать?
Скачал библиотеку libjpeg с сайта www.ijg.org (jpegsr9a.zip) для использования в своем проекте. Не смог разобраться, как ее скомпилировать...

Построение libjpeg-turbo
проблемы с построением libjpeg-turbo http://sourceforge.net/projects/libjpeg-turbo/ скачал сорцы, выполнил создались...

libjpeg - дайте мануал!
Научите меня пользоваться libjpeg. Я в интернете не нашел ничего хорошего. Я уже гуглил - поиск не дал результатов!

Как компилить программу с libjpeg?
Я не понимаю, как компилить программу с libjpeg, если я использую Visual Studio. Г* командная строка - не находит nmake.

И снова связка (Dev C++) + (libjpeg)
Я понимаю, что могу получить за тривиальный вопрос. Но. Сколько я не переколбасил инфы проблему не решил. Необходимо связать Dev C++...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
1С: Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит значение перечислений. / / Событие "НачалоВыбора" реквизита на форме. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru