添加黑白图像转换处理
This commit is contained in:
parent
e3d672a666
commit
0439185933
|
@ -13,6 +13,73 @@ static int ui_default_callback(scanner_handle, int, void*, unsigned int*, void*)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
static std::string bmp_821(unsigned char* bits/*bits data*/, int w, int h, int* lbytes, bool line_align_4)
|
||||
{
|
||||
static unsigned int g_bmp8_pallete[] = {
|
||||
0x00000000, 0x00800000, 0x00008000, 0x00808000, 0x00000080, 0x00800080, 0x00008080, 0x00c0c0c0, 0x00c0dcc0, 0x00a6caf0, 0x00402000, 0x00602000, 0x00802000, 0x00a02000, 0x00c02000, 0x00e02000
|
||||
, 0x00004000, 0x00204000, 0x00404000, 0x00604000, 0x00804000, 0x00a04000, 0x00c04000, 0x00e04000, 0x00006000, 0x00206000, 0x00406000, 0x00606000, 0x00806000, 0x00a06000, 0x00c06000, 0x00e06000
|
||||
, 0x00008000, 0x00208000, 0x00408000, 0x00608000, 0x00808000, 0x00a08000, 0x00c08000, 0x00e08000, 0x0000a000, 0x0020a000, 0x0040a000, 0x0060a000, 0x0080a000, 0x00a0a000, 0x00c0a000, 0x00e0a000
|
||||
, 0x0000c000, 0x0020c000, 0x0040c000, 0x0060c000, 0x0080c000, 0x00a0c000, 0x00c0c000, 0x00e0c000, 0x0000e000, 0x0020e000, 0x0040e000, 0x0060e000, 0x0080e000, 0x00a0e000, 0x00c0e000, 0x00e0e000
|
||||
, 0x00000040, 0x00200040, 0x00400040, 0x00600040, 0x00800040, 0x00a00040, 0x00c00040, 0x00e00040, 0x00002040, 0x00202040, 0x00402040, 0x00602040, 0x00802040, 0x00a02040, 0x00c02040, 0x00e02040
|
||||
, 0x00004040, 0x00204040, 0x00404040, 0x00604040, 0x00804040, 0x00a04040, 0x00c04040, 0x00e04040, 0x00006040, 0x00206040, 0x00406040, 0x00606040, 0x00806040, 0x00a06040, 0x00c06040, 0x00e06040
|
||||
, 0x00008040, 0x00208040, 0x00408040, 0x00608040, 0x00808040, 0x00a08040, 0x00c08040, 0x00e08040, 0x0000a040, 0x0020a040, 0x0040a040, 0x0060a040, 0x0080a040, 0x00a0a040, 0x00c0a040, 0x00e0a040
|
||||
, 0x0000c040, 0x0020c040, 0x0040c040, 0x0060c040, 0x0080c040, 0x00a0c040, 0x00c0c040, 0x00e0c040, 0x0000e040, 0x0020e040, 0x0040e040, 0x0060e040, 0x0080e040, 0x00a0e040, 0x00c0e040, 0x00e0e040
|
||||
, 0x00000080, 0x00200080, 0x00400080, 0x00600080, 0x00800080, 0x00a00080, 0x00c00080, 0x00e00080, 0x00002080, 0x00202080, 0x00402080, 0x00602080, 0x00802080, 0x00a02080, 0x00c02080, 0x00e02080
|
||||
, 0x00004080, 0x00204080, 0x00404080, 0x00604080, 0x00804080, 0x00a04080, 0x00c04080, 0x00e04080, 0x00006080, 0x00206080, 0x00406080, 0x00606080, 0x00806080, 0x00a06080, 0x00c06080, 0x00e06080
|
||||
, 0x00008080, 0x00208080, 0x00408080, 0x00608080, 0x00808080, 0x00a08080, 0x00c08080, 0x00e08080, 0x0000a080, 0x0020a080, 0x0040a080, 0x0060a080, 0x0080a080, 0x00a0a080, 0x00c0a080, 0x00e0a080
|
||||
, 0x0000c080, 0x0020c080, 0x0040c080, 0x0060c080, 0x0080c080, 0x00a0c080, 0x00c0c080, 0x00e0c080, 0x0000e080, 0x0020e080, 0x0040e080, 0x0060e080, 0x0080e080, 0x00a0e080, 0x00c0e080, 0x00e0e080
|
||||
, 0x000000c0, 0x002000c0, 0x004000c0, 0x006000c0, 0x008000c0, 0x00a000c0, 0x00c000c0, 0x00e000c0, 0x000020c0, 0x002020c0, 0x004020c0, 0x006020c0, 0x008020c0, 0x00a020c0, 0x00c020c0, 0x00e020c0
|
||||
, 0x000040c0, 0x002040c0, 0x004040c0, 0x006040c0, 0x008040c0, 0x00a040c0, 0x00c040c0, 0x00e040c0, 0x000060c0, 0x002060c0, 0x004060c0, 0x006060c0, 0x008060c0, 0x00a060c0, 0x00c060c0, 0x00e060c0
|
||||
, 0x000080c0, 0x002080c0, 0x004080c0, 0x006080c0, 0x008080c0, 0x00a080c0, 0x00c080c0, 0x00e080c0, 0x0000a0c0, 0x0020a0c0, 0x0040a0c0, 0x0060a0c0, 0x0080a0c0, 0x00a0a0c0, 0x00c0a0c0, 0x00e0a0c0
|
||||
, 0x0000c0c0, 0x0020c0c0, 0x0040c0c0, 0x0060c0c0, 0x0080c0c0, 0x00a0c0c0, 0x00fffbf0, 0x00a0a0a4, 0x00808080, 0x00ff0000, 0x0000ff00, 0x00ffff00, 0x000000ff, 0x00ff00ff, 0x0000ffff, 0x00ffffff
|
||||
};
|
||||
int l = (w + 31) / 32 * 4,
|
||||
size = l * h,
|
||||
line_bytes = (w + 3) / 4 * 4;
|
||||
std::string f("");
|
||||
unsigned char* data = nullptr;
|
||||
unsigned int* pallete = g_bmp8_pallete;
|
||||
|
||||
if (!line_align_4)
|
||||
{
|
||||
l = (w + 7) / 8;
|
||||
size = l * h;
|
||||
}
|
||||
if (lbytes && *lbytes)
|
||||
line_bytes = *lbytes;
|
||||
f.resize(size);
|
||||
data = (unsigned char*)&f[0];
|
||||
for (int i = 0; i < h; ++i)
|
||||
{
|
||||
unsigned char v = 0,
|
||||
*dst = data;
|
||||
for (int j = 0; j < w; ++j)
|
||||
{
|
||||
v <<= 1;
|
||||
|
||||
unsigned char pixel = ((pallete[bits[j]] & 0x0ff) + ((pallete[bits[j]] >> 8) & 0x0ff) + ((pallete[bits[j]] >> 16) & 0x0ff)) / 3;
|
||||
if (pixel >= 128)
|
||||
v |= 1;
|
||||
if ((j + 1) % 8 == 0)
|
||||
{
|
||||
*dst++ = v;
|
||||
v = 0;
|
||||
}
|
||||
}
|
||||
if (v)
|
||||
{
|
||||
v <<= 8 - (w % 8);
|
||||
*dst++ = v;
|
||||
}
|
||||
|
||||
data += l;
|
||||
bits += line_bytes;
|
||||
}
|
||||
if (lbytes)
|
||||
*lbytes = l;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// hg_scanner
|
||||
|
@ -1737,14 +1804,14 @@ bool hg_scanner::waiting_for_memory_enough(unsigned need_bytes)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void hg_scanner::copy_to_sane_image_header(SANE_Parameters* header, int w, int h, int line_bytes, int channels)
|
||||
void hg_scanner::copy_to_sane_image_header(SANE_Parameters* header, int w, int h, int line_bytes, int channels, int bits)
|
||||
{
|
||||
if (channels == 3)
|
||||
header->format = SANE_FRAME_RGB;
|
||||
else
|
||||
header->format = SANE_FRAME_GRAY;
|
||||
header->depth = 8; // 此处指每一个颜色分量的位深,我们的扫描仪固定为“8”
|
||||
header->last_frame = SANE_TRUE; // 一幅图片如果各个分量相互分离,则最后一个分量的时候设置为true。彩色图像RGB时也只有一“帧”,所以也为true
|
||||
header->depth = bits >= 8 ? 8 : bits; // 此处指每一个颜色分量的位深,我们的扫描仪固定为“8”
|
||||
header->last_frame = SANE_TRUE; // 一幅图片如果各个分量相互分离,则最后一个分量的时候设置为true。彩色图像RGB时也只有一“帧”,所以也为true
|
||||
header->pixels_per_line = w;
|
||||
header->lines = h;
|
||||
header->bytes_per_line = line_bytes;
|
||||
|
@ -1778,11 +1845,23 @@ int hg_scanner::save_usb_data(std::shared_ptr<std::vector<char>> data)
|
|||
}
|
||||
int hg_scanner::save_final_image(hg_imgproc::LPIMGHEAD head, void* buf)
|
||||
{
|
||||
std::string bw("");
|
||||
|
||||
final_img_index_++;
|
||||
if (image_prc_param_.bits.color_mode == COLOR_MODE_BLACK_WHITE)
|
||||
{
|
||||
int old = head->line_bytes;
|
||||
bw = bmp_821((unsigned char*)buf, head->width, head->height, &head->line_bytes, async_io_);
|
||||
buf = &bw[0];
|
||||
head->channels = head->bits = 1;
|
||||
head->total_bytes = head->line_bytes * head->height;
|
||||
VLOG_MINI_4(LOG_LEVEL_DEBUG_INFO, "convert to 1-bit bmp(%d * %d), total = %u, len = %u\n", head->width, head->height, head->total_bytes, bw.length());
|
||||
}
|
||||
|
||||
if (async_io_)
|
||||
{
|
||||
SANE_Image img;
|
||||
copy_to_sane_image_header(&img.header, head->width, head->height, head->line_bytes, head->channels);
|
||||
copy_to_sane_image_header(&img.header, head->width, head->height, head->line_bytes, head->channels, head->bits);
|
||||
img.data = (unsigned char*)buf;
|
||||
img.bytes = head->total_bytes;
|
||||
|
||||
|
@ -2153,7 +2232,7 @@ int hg_scanner::get_image_info(SANE_Parameters* ii)
|
|||
if (!final_imgs_.front(&imh))
|
||||
ret = SCANNER_ERR_NO_DATA;
|
||||
else
|
||||
copy_to_sane_image_header(ii, imh.width, imh.height, imh.line_bytes, imh.channels);
|
||||
copy_to_sane_image_header(ii, imh.width, imh.height, imh.line_bytes, imh.channels, imh.bits);
|
||||
}
|
||||
|
||||
if (ret == SCANNER_ERR_NO_DATA /*&& final_img_index_ == 0*/)
|
||||
|
@ -2162,7 +2241,7 @@ int hg_scanner::get_image_info(SANE_Parameters* ii)
|
|||
ret = SCANNER_ERR_NO_DATA;
|
||||
else
|
||||
{
|
||||
ii->depth = 8;
|
||||
ii->depth = image_prc_param_.bits.color_mode == COLOR_MODE_BLACK_WHITE ? 1 : 8;
|
||||
ii->last_frame = SANE_TRUE;
|
||||
ii->format = image_prc_param_.bits.color_mode == COLOR_MODE_24_BITS || image_prc_param_.bits.color_mode == COLOR_MODE_AUTO_MATCH ?
|
||||
SANE_FRAME_RGB : SANE_FRAME_GRAY;
|
||||
|
|
|
@ -268,7 +268,7 @@ protected:
|
|||
int notify_ui_working_status(const char* msg, int ev = SANE_EVENT_STATUS, int status = SCANNER_ERR_OK);
|
||||
bool waiting_for_memory_enough(unsigned need_bytes);
|
||||
|
||||
void copy_to_sane_image_header(SANE_Parameters* header, int w, int h, int line_bytes, int channels);
|
||||
void copy_to_sane_image_header(SANE_Parameters* header, int w, int h, int line_bytes, int channels, int bits);
|
||||
int save_usb_data(std::shared_ptr<std::vector<char>> data);
|
||||
int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf);
|
||||
|
||||
|
|
Loading…
Reference in New Issue