Страницы

Поиск по вопросам

пятница, 27 декабря 2019 г.

Сканирование с использованием библиотеки libsane

#linux #c #gtk #sane


Получаю изображение маленькой строки расположенной в конце страницы.
Как передать настройки в сканер, чтобы получить всю страницу?

Вот мой код:

#include 
#include 
#include 

void button_cb(GtkButton *button,gpointer  user_data)
{
    SANE_Byte *buf = NULL;
    SANE_Status status;
    const SANE_Device **device_list = NULL;
    SANE_Handle h;
    SANE_Parameters p;
    const SANE_Option_Descriptor *d;


    buf = g_malloc(8000000); // 8 MB
    if(!buf)
    {
        g_print("Память не выделена\n");
    }

    status = sane_init(NULL, NULL);  // Инициализация
    g_print("sane_init: %d\n", (int)status);

    status = sane_get_devices (&device_list, FALSE); // Получение списка устройств

    for(int i = 0; device_list[i] != NULL; ++i)
    {
        g_print("Device: %s\n", device_list[i]->name);
    }


    status = sane_open(device_list[1]->name, &h); // Получение дескриптора устройства
    g_print("sane_open: %d\n", (int)status);

    // Установка параметров
    //SANE_Status sane_control_option(SANE_Handle h, SANE_Int n, SANE_Action a, void
*v,SANE_Int * i);


    d = sane_get_option_descriptor(h, n); // Дескриптор опций
    g_print("Status,%d\n", (int)status);



    status = sane_start(h);
    g_print("sane_start:,%d\n", (int)status);



    status = sane_get_parameters(h, &p); // Получение параметров со сканера
    g_print("sane_get_parameters: %d\n", (int)status);


    // Чтение со сканера

    SANE_Int len = 0;
    int n = 0;

    while(status != SANE_STATUS_EOF)
    {
        status = sane_read(h, buf + n, 4000000, &len);
        if(len != 0)
        {   
            n = n + len;
        }
    }



    // Сохранение в файл

    GBytes *data;
    data = g_bytes_new(buf, (gsize)n);

    GdkPixbuf *pixbuf;
    pixbuf = gdk_pixbuf_new_from_bytes(data, GDK_COLORSPACE_RGB, FALSE, p.depth,
p.pixels_per_line, p.lines, p.bytes_per_line);

    gdk_pixbuf_save(pixbuf, "image.jpeg", "jpeg", NULL, "quality", "100", NULL);
                      


    // Освобождение ресурсов

    g_object_unref(pixbuf);

    g_free(buf);
    sane_cancel(h);
    sane_close(h);
    sane_exit();


}



int main(int argc, char **argv)
{
    GtkWidget *window;
    GtkWidget *box;
    GtkWidget *button;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Библиотека Sane");
    gtk_window_set_default_size(GTK_WINDOW(window), 320, 240);

    box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
    gtk_container_add(GTK_CONTAINER(window), box);

    gtk_widget_set_halign(box,GTK_ALIGN_CENTER);
    gtk_widget_set_valign(box,GTK_ALIGN_CENTER);

    button = gtk_button_new_with_label("Сканирование");
    gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 10);
    g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_cb), NULL);

    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}


Исправил — получаю полное изображение. Меняю настройки сканера на c RGB на GRAY —
gdk_pixbuf_new_from_bytes ругается. 

Выхлоп в консоли:


  (main:8397): GdkPixbuf-CRITICAL **: gdk_pixbuf_new_from_bytes: assertion 'bits_per_sample
== 8' failed
  
  (main:8397): GdkPixbuf-CRITICAL **: gdk_pixbuf_scale_simple: assertion 'GDK_IS_PIXBUF
(src)' failed
  
  (main:8397): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_rowstride: assertion 'GDK_IS_PIXBUF
(pixbuf)' failed
  
  (main:8397): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_n_channels: assertion 'GDK_IS_PIXBUF
(pixbuf)' failed
  
  (main:8397): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_width: assertion 'GDK_IS_PIXBUF
(pixbuf)' failed
  
  (main:8397): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_height: assertion 'GDK_IS_PIXBUF
(pixbuf)' failed

    


Ответы

Ответ 1



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

Комментариев нет:

Отправить комментарий