powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Создание скриншота с глубиной цвета 8 bit
7 сообщений из 7, страница 1 из 1
Создание скриншота с глубиной цвета 8 bit
    #39950483
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет! Помогите пожалуйста разобраться как сделать восьми битный скриншот.
Я могу сделать 24 и 16 битный а вот 8 битный не получается, наверное не правильно битовую маску указываю. Вот пример кода.
Код: java
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.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
package javaapplication28;

import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;

import com.sun.jna.Memory;
import com.sun.jna.platform.win32.GDI32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HBITMAP;
import com.sun.jna.platform.win32.WinDef.HDC;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinGDI;
import com.sun.jna.platform.win32.WinGDI.BITMAPINFO;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.DataBufferUShort;

public class TestGDI {

    // 24bit
    public static final DirectColorModel SCREENSHOT_COLOR_MODEL_24 = new DirectColorModel(24, 0x00FF0000, 0xFF00, 0xFF);
    // 16bit
    public static final DirectColorModel SCREENSHOT_COLOR_MODEL_16 = new DirectColorModel(16, 0x7C00, 0x3E0, 0x1F);
    // 8bit
    public static final DirectColorModel SCREENSHOT_COLOR_MODEL_8 = new DirectColorModel(8, 3, 3, 2);

    public static final int[] SCREENSHOT_BAND_MASKS_24 = {
        SCREENSHOT_COLOR_MODEL_24.getRedMask(),
        SCREENSHOT_COLOR_MODEL_24.getGreenMask(),
        SCREENSHOT_COLOR_MODEL_24.getBlueMask()
    };
    public static final int[] SCREENSHOT_BAND_MASKS_16 = {
        SCREENSHOT_COLOR_MODEL_16.getRedMask(),
        SCREENSHOT_COLOR_MODEL_16.getGreenMask(),
        SCREENSHOT_COLOR_MODEL_16.getBlueMask()
    };
    public static final int[] SCREENSHOT_BAND_MASKS_8 = {
        SCREENSHOT_COLOR_MODEL_8.getRedMask(),
        SCREENSHOT_COLOR_MODEL_8.getGreenMask(),
        SCREENSHOT_COLOR_MODEL_8.getBlueMask()
    };

    public static BufferedImage getScreenshot(HWND target, int width, int height) throws Exception {
        int bit = 8;
        HDC hdcTarget = User32.INSTANCE.GetDC(target);
        HDC hdcTargetMem = GDI32.INSTANCE.CreateCompatibleDC(hdcTarget);
        HBITMAP hBitmap = GDI32.INSTANCE.CreateCompatibleBitmap(hdcTarget, width, height);
        GDI32.INSTANCE.SelectObject(hdcTargetMem, hBitmap);
        GDI32.INSTANCE.BitBlt(hdcTargetMem, 0, 0, width, height, hdcTarget, 0, 0, GDI32.SRCCOPY);
        //
        int bufferSize = width * height;
        int pixelByte;
        DirectColorModel colorModel;
        int[] bandMask;
        short bitCount;
        //
        switch (bit) {
            case 24:
                pixelByte = 4;
                colorModel = SCREENSHOT_COLOR_MODEL_24;
                bandMask = SCREENSHOT_BAND_MASKS_24;
                bitCount = 32;
                break;
            case 16:
                pixelByte = 2;
                colorModel = SCREENSHOT_COLOR_MODEL_16;
                bandMask = SCREENSHOT_BAND_MASKS_16;
                bitCount = 16;
                break;
            case 8:
                pixelByte = 1;
                colorModel = SCREENSHOT_COLOR_MODEL_8;
                bandMask = SCREENSHOT_BAND_MASKS_8;
                bitCount = 8;
                break;
            default:
                throw new Exception("unknown bit");
        }
        //
        BITMAPINFO bmi = new BITMAPINFO();
        bmi.bmiHeader.biWidth = width;
        bmi.bmiHeader.biHeight = -height;
        bmi.bmiHeader.biPlanes = 1;
        bmi.bmiHeader.biBitCount = bitCount;
        bmi.bmiHeader.biCompression = WinGDI.BI_RGB;
        //

        Memory buffer = new Memory(bufferSize * pixelByte);
        GDI32.INSTANCE.GetDIBits(hdcTarget, hBitmap, 0, height, buffer, bmi, WinGDI.DIB_RGB_COLORS);
        DataBuffer dataBuffer;
        switch (bit) {
            case 24:
                dataBuffer = new DataBufferInt(buffer.getIntArray(0, bufferSize), bufferSize);
                break;
            case 16:
                dataBuffer = new DataBufferUShort(buffer.getShortArray(0, bufferSize), bufferSize);
                break;
            case 8:
                dataBuffer = new DataBufferByte(buffer.getByteArray(0, bufferSize), bufferSize);
                break;
            default:
                throw new Exception("unknown bit");
        }

        WritableRaster raster = Raster.createPackedRaster(dataBuffer, width, height, width, bandMask, null);
        GDI32.INSTANCE.DeleteObject(hBitmap);
        GDI32.INSTANCE.DeleteDC(hdcTargetMem);
        User32.INSTANCE.ReleaseDC(target, hdcTarget);
        return new BufferedImage(colorModel, raster, false, null);
    }
}
...
Рейтинг: 0 / 0
Создание скриншота с глубиной цвета 8 bit
    #39950513
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обычно RGB пространство цветов заканчивается на 16 битах.

Всё что ниже - индексный цвет. Тоесть цвет №1==красный .... цвет №256 == черный.
Цвета рандомные или по выбору пользователя.
И тут какоаз на сцене появляется выбор палитры. Начиная от стандартных
VGA-256 и заканивая адаптивными палитрами которые беруться из
центров кластеров исходного цветового пространства картики.
Можно также 8 бит представить как RGB=3:3:2 бита
но качество такой адаптации будет ужасным. Я сам пробовал.

Потом еще Microsoft различает 4-х битный цвет. И 1-битный для би-тональных картинок.
...
Рейтинг: 0 / 0
Создание скриншота с глубиной цвета 8 bit
    #39950523
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Вы все правильно и интересно говорите, как это превратить в рабочий код? :)
...
Рейтинг: 0 / 0
Создание скриншота с глубиной цвета 8 bit
    #39950527
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я опираюсь на свои базовые знания Windows и графики. Но в Java
я никогда не использовал пакет com.sun.jna.platform.win32

Тоесть то что я написал - теория. И как правильно обращатся с этим пакетом хз.
...
Рейтинг: 0 / 0
Создание скриншота с глубиной цвета 8 bit
    #39950550
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Как превратить в знания в Java я знаю. Сможете подсказать на примере с++ например?
Я так понимаю что всё дело в правильно заполнении массива RGBQUAD?
...
Рейтинг: 0 / 0
Создание скриншота с глубиной цвета 8 bit
    #39950570
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да.
1) Создаешь 256 штук RGBQUAD. (палитра)
2) Заполняешь их любыми цветами (но желательно брать самые популярные из изсходной картинки)
3) Генеришь destination и на каждый пиксел находишь из палитры самый близкий цвет
(по декартову расстоянию) или там есть более точная формула. Декартово расстояние
но перед каждым цветом есть весовой коэффициент. Для зеленого он самый большой.
...
Рейтинг: 0 / 0
Создание скриншота с глубиной цвета 8 bit
    #39950999
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А зачем такой странных хардкод?
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
    public static BufferedImage getScreenshot(HWND target, int width, int height) throws Exception {
        int bit = 8;
        HDC hdcTarget = User32.INSTANCE.GetDC(target);
        HDC hdcTargetMem = GDI32.INSTANCE.CreateCompatibleDC(hdcTarget);
        HBITMAP hBitmap = GDI32.INSTANCE.CreateCompatibleBitmap(hdcTarget, width, height);
        GDI32.INSTANCE.SelectObject(hdcTargetMem, hBitmap);
        GDI32.INSTANCE.BitBlt(hdcTargetMem, 0, 0, width, height, hdcTarget, 0, 0, GDI32.SRCCOPY);
        //
        int bufferSize = width * height;
        int pixelByte;
        DirectColorModel colorModel;
        int[] bandMask;
        short bitCount;
        //
        switch (bit) {
            case 24:
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Создание скриншота с глубиной цвета 8 bit
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]