This commit is contained in:
13038267101 2023-12-07 17:01:15 +08:00
commit c6b255a18a
18 changed files with 268 additions and 110 deletions

View File

@ -193,22 +193,28 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
cv::Mat dstROI;
if (isDesaskew && rect.angle != 0)
{
cv::RotatedRect rect_temp = rect;
if (rect_temp.size.width > dst.cols)
rect_temp.size.width = dst.cols;
if (rect_temp.size.height > dst.rows)
rect_temp.size.height = dst.rows;
cv::Point2f srcTri[4], dstTri[3];
rect.points(srcTri);
rect_temp.points(srcTri);
srcTri[0].x -= 1;
srcTri[1].x -= 1;
srcTri[2].x -= 1;
int w = rect.size.width;
int h = rect.size.height;
int w = rect_temp.size.width;
int h = rect_temp.size.height;
int x = (dst.cols - w) / 2;
int y = (dst.rows - h) / 2;
dstTri[0] = cv::Point2f(x, y + h);
dstTri[1] = cv::Point2f(x, y);
dstTri[2] = cv::Point2f(x + w, y);
dstTri[0] = cv::Point2f(0, h);
dstTri[1] = cv::Point2f(0, 0);
dstTri[2] = cv::Point2f(w, 0);
dstROI = dst(cv::Rect(x, y, w, h) & cv::Rect(0, 0, dst.cols, dst.rows));
myWarpAffine(src, dstROI, cv::getAffineTransform(srcTri, dstTri), dstROI.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar::all(0));
myWarpAffine(src, dstROI, cv::getAffineTransform(srcTri, dstTri), dstROI.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, blankColor);
}
else
{

View File

@ -35,7 +35,8 @@
2023/05/23 v1.5.6 BUG
2023/11/02 v1.6
2023/12/05 v1.6.1 BUG
* v1.6.1
2023/12/06 v1.6.2 BUG
* v1.6.2
* ====================================================
*/

View File

@ -207,31 +207,45 @@ namespace hg
cv::Scalar getBackGroundColor(const cv::Mat& image, const cv::Mat& mask, int threshold)
{
cv::Scalar bgc;
cv::Mat mv[3];
cv::split(image, mv);
float range[] = { 0, 256 };
const float* ranges = { range };
int histSize = 256;
cv::Mat hist[3];
double min, max;
cv::Point maxLoc;
for (int i = 0; i < 3; i++)
cv::Scalar bgc;
if (image.channels() == 3)
{
cv::calcHist(&mv[i], 1, 0, mask, hist[i], 1, &histSize, &ranges);
cv::Mat mv[3];
cv::split(image, mv);
cv::Mat hist[3];
for (int i = 0; i < 3; i++)
{
cv::calcHist(&mv[i], 1, 0, mask, hist[i], 1, &histSize, &ranges);
int index_max = 0;
int max_value = 0;
for (size_t j = threshold; j < 256; j++)
if (hist[i].at<float>(j) > max_value)
{
index_max = j;
max_value = hist[i].at<float>(j);
}
bgc[i] = index_max;
}
}
else
{
cv::Mat hist;
cv::calcHist(&image, 1, 0, mask, hist, 1, &histSize, &ranges);
int index_max = 0;
int max_value = 0;
for (size_t j = threshold; j < 256; j++)
if (hist[i].at<float>(j) > max_value)
if (hist.at<float>(j) > max_value)
{
index_max = j;
max_value = hist[i].at<float>(j);
max_value = hist.at<float>(j);
}
bgc[i] = index_max;
bgc = cv::Scalar::all(index_max);
}
return bgc;

View File

@ -11,7 +11,8 @@
* 2023/12/01 v1.4 getBackGroundColor算法
* 2023/12/02 v1.4.1 getBackGroundColor增加threshold阈值
* 2023/12/04 v1.4.2 opencv版本接口
* v1.4.2
* 2023/12/05 v1.4.3 getBackGroundColor支持单通道图像背景色识别
* v1.4.3
* ====================================================
*/

View File

@ -622,6 +622,7 @@ typedef struct _scan_conf
double discare_meanth; /**< 调过空白页文稿底色阈值>*/
bool en_contaminationdetection; /**< 脏污检测使能>*/
bool detect_size_diascard_blank; /**< 基于压缩图像大小跳过空白页使能*/
int refuseInflow_level; /**< 防止渗透等级*/
uint32_t reserve[1024]; /**< 预留4096字节做协议扩展*/
}SCANCONF ,*LPSCANCONF;
//图像参数设置 -OVER

View File

@ -204,6 +204,30 @@ hg_scanner::hg_scanner(ScannerSerial serial, const char* dev_name, usb_io* io, i
{
VLOG_MINI_1(LOG_LEVEL_WARNING, "temporary image folder: %s\n", final_path_.c_str());
final_path_ += PATH_SEPARATOR;
// delete previous failed images, check the name as pattern '%04d-xxx.jpg'
std::vector<std::string> files;
hg_log::get_foler_files((final_path_ + "failedimgs").c_str(), files);
for (auto& v : files)
{
size_t pos = v.rfind(PATH_SEPARATOR[0]);
std::string name("");
char num[20] = { 0 };
if (pos == std::string::npos)
name = v;
else
name = v.substr(pos + 1);
sprintf(num, "%04d-", atoi(name.c_str()));
if (name.find(num) == 0)
{
pos = name.rfind('.');
if(pos != std::string::npos && STRICMP(name.c_str() + pos, ".jpg") == 0)
remove(v.c_str());
}
}
rmdir((final_path_ + "failedimgs").c_str());
hg_log::create_folder((final_path_ + "failedimgs").c_str());
}
else
{
@ -1070,13 +1094,15 @@ void hg_scanner::thread_handle_image_process(void)
if (!ImagePrc_pHandle_)
{
VLOG_MINI_1(LOG_LEVEL_FATAL, "[thread_handle_image_process]:Get Image Process is NULL pid is %d.\n", pid_);
stop_fatal_ = SCANNER_ERR_INSUFFICIENT_MEMORY;
stop_fatal_ = SCANNER_ERR_IMAGE_PROC_FATAL;
do_stop();
invoke_stop = true;
break;
}
}
image_process(tiny_buffer, id);
invoke_stop = !image_process(tiny_buffer, id);
if (invoke_stop)
break;
}
catch (const std::exception& e)
{
@ -1085,20 +1111,24 @@ void hg_scanner::thread_handle_image_process(void)
is_dpi_color_check = false;
stop_fatal_ = SCANNER_ERR_DEVICE_DISTORTION;
}
else
else if (e.what() && strstr(e.what(), "Insufficient "))
stop_fatal_ = SCANNER_ERR_INSUFFICIENT_MEMORY;
else
stop_fatal_ = SCANNER_ERR_IMAGE_PROC_FATAL;
VLOG_MINI_1(LOG_LEVEL_FATAL, "[thread_handle_image_process]:is opencv Fatal and stop scanner: %s\n", e.what());
do_stop();
invoke_stop = true;
save_exception_image(tiny_buffer, id, "opencv-excep");
break;
}
catch (...)
{
VLOG_MINI_1(LOG_LEVEL_FATAL, "[thread_handle_image_process]:stop scanner!!! Insufficient memory when proecss image with %d bytes.\n", tiny_buffer->size());
stop_fatal_ = SCANNER_ERR_INSUFFICIENT_MEMORY;
stop_fatal_ = SCANNER_ERR_IMAGE_PROC_FATAL;
do_stop();
invoke_stop = true;
save_exception_image(tiny_buffer, id, "opencv-excep");
break;
}
}
@ -3664,6 +3694,7 @@ int hg_scanner::save_usb_data(std::shared_ptr<tiny_buffer> data)
}
if (!data->swap())
{
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "USB packet(%04d) swap failed.\n", usb_img_index_);
ret = SCANNER_ERR_OPEN_FILE_FAILED;
}
else
@ -3699,7 +3730,7 @@ int hg_scanner::save_usb_data(std::shared_ptr<tiny_buffer> data)
{
VLOG_MINI_1(LOG_LEVEL_WARNING, "Warning: memory usage(%.2fMB) maybe leading exception!\r\n", Memoryusae);
}
imgs_.Put(data, data->size(), hg_scanner_mgr::unique_id());
imgs_.Put(data, data->size(), usb_img_index_);
if (wait_img_.is_waiting())
wait_img_.notify();
}
@ -5147,24 +5178,62 @@ int hg_scanner::get_scan_is_sleep(SANE_Bool& data)
{
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
}
void hg_scanner::image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id)
void hg_scanner::save_exception_image(std::shared_ptr<tiny_buffer>& buffer, int sn, const char* desc)
{
char name[128] = { 0 };
FILE* dst = nullptr;
sprintf(name, "%04d-%s.jpg", sn, desc);
dst = fopen((final_path_ + "failedimgs" + PATH_SEPARATOR + name).c_str(), "wb");
if (dst)
{
unsigned int off = 0,
len = buffer->size(),
size = len;
unsigned char* mem = buffer->data(off, &size);
while (mem)
{
fwrite(mem, 1, size, dst);
off += size;
if (off >= len)
break;
else
{
size = len - off;
mem = buffer->data(off, &size);
}
}
fclose(dst);
}
}
bool hg_scanner::image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id)
{
if (!buffer.get() || !ImagePrc_pHandle_)
{
return;
VLOG_MINI_1(LOG_LEVEL_FATAL, "process image %d fatal: data is empty or image-process object is not initialized, stop scanning ...\n", id);
do_stop();
return false;
}
int ret = SCANNER_ERR_OK;
hg_imgproc::IMGPRCPARAM param = get_image_process_object(pid_);
hg_imgproc::IMGHEAD ih;
int err = SCANNER_ERR_OK,
index = 0;
std::string fimg(final_path_ + "failedimgs" + PATH_SEPARATOR);
void* buf = NULL;
hg_imgproc::load_buffer(ImagePrc_pHandle_, buffer);
int imgStatus = buffer->get_image_statu();
hg_imgproc::decode(ImagePrc_pHandle_, pid_, &img_conf_, &param, correction_image_map_);
err = hg_imgproc::decode(ImagePrc_pHandle_, pid_, &img_conf_, &param, correction_image_map_);
(this->*dump_img_)(ImagePrc_pHandle_, "decode");
if (err != SCANNER_ERR_OK)
{
save_exception_image(buffer, id, "decode");
VLOG_MINI_2(LOG_LEVEL_FATAL, "Decode image(%d) with bytes %u failed, stop scanning.\n", id, buffer->size());
do_stop();
return false;
}
if (is_dpi_color_check)
{
@ -5293,18 +5362,7 @@ void hg_scanner::image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id
if ((img_conf_.refuseInflow) && (pid_ != 0x239 && pid_ != 0x439))
{
int lv = image_prc_param_.bits.is_permeate_lv_; //image_prc_param_.bits.is_permeate_lv_ = 0 1 2 3 4
if (0 == lv)
lv = 20;
else if (1 == lv)
lv = 30;
else if (2 == lv)
lv = 40;
else if (3 == lv)
lv = 50;
else if (4 == lv)
lv = 60;
int lv = image_prc_param_.bits.is_permeate_lv_ * 10 + 20; //image_prc_param_.bits.is_permeate_lv_ = 0 1 2 3 4
hg_imgproc::antiInflow(ImagePrc_pHandle_, lv);
(this->*dump_img_)(ImagePrc_pHandle_, "antiInflow");
@ -5392,7 +5450,7 @@ void hg_scanner::image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id
if (is_multiout)//239
{
int multi_out = img_conf_.multiOutput;
err = hg_imgproc::multi_out(ImagePrc_pHandle_, multi_out);
err = hg_imgproc::multi_out(ImagePrc_pHandle_, multi_out, bw_threshold_);
(this->*dump_img_)(ImagePrc_pHandle_, "multi_out");
}
}
@ -5412,7 +5470,9 @@ void hg_scanner::image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id
if (bmpdata.empty())
{
status_ = SCANNER_ERR_NO_DATA;
return;
VLOG_MINI_1(LOG_LEVEL_FATAL, "process image %d fatal: image data is empty! stop scanning ...\n", id);
do_stop();
return false;
}
buf = bmpdata.data();
ih.total_bytes = bmpdata.size();
@ -5425,6 +5485,8 @@ void hg_scanner::image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id
save_final_image(&ih, buf, id);
id = -1;
}
return true;
}
int hg_scanner::image_configuration(SCANCONF& ic)
{
@ -5541,6 +5603,7 @@ int hg_scanner::image_configuration(SCANCONF& ic)
ic.is_autotext = image_prc_param_.bits.text_direction == TEXT_DIRECTION_AUTO ? 1 : 0;
ic.isfillcolor = is_color_fill;
ic.refuseInflow = image_prc_param_.bits.is_permeate;
ic.refuseInflow_level = image_prc_param_.bits.is_permeate_lv_ * 10 + 20;
ic.colorCorrection = 0;
ic.removeMorr = image_prc_param_.bits.remove_morr;
ic.errorExtention = image_prc_param_.bits.error_extention;//

View File

@ -130,7 +130,8 @@ class hg_scanner
void working_begin(void*);
void working_done(void*);
void image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id);
void save_exception_image(std::shared_ptr<tiny_buffer>& buffer, int sn, const char* desc);
bool image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id); // 返回true - continue; false - exit and invoked do_stop
void reset_custom_area_range(int paper);
float reset_custom_area_jsn_value(const char* name, double& var, float range_l, float range_u, float value_l, float value_u); // return cur value
int set_color_change(void);

View File

@ -217,7 +217,20 @@ void hg_scanner_200::thread_handle_usb_read(void)
}
io_->set_timeout(200);
pop_image();
ret = pop_image();
if (ret != SCANNER_ERR_OK)
{
hg_log::log(LOG_LEVEL_FATAL, "Try ONCE pop_firt_image after 100ms ...\n");
std::this_thread::sleep_for(std::chrono::milliseconds(100));
ret = pop_image();
if (ret)
{
hg_log::log(LOG_LEVEL_FATAL, "pop_firt_image failed, stop scanning!\n");
do_stop();
status_ = ret;
break;
}
}
sw.reset();
first = false;
}

View File

@ -719,6 +719,7 @@ int hg_scanner_239::read_one_image_from_usb(SANE_Image_Statu statu)
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
else // if (ret == SCANNER_ERR_OK)
{
io_->set_timeout(1000);
std::lock_guard<std::mutex> lock(io_lock_);
// write reading command
@ -726,7 +727,7 @@ int hg_scanner_239::read_one_image_from_usb(SANE_Image_Statu statu)
buf->set_image_statu(statu);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
//std::this_thread::sleep_for(std::chrono::milliseconds(10));
r = total;
if (ret == SCANNER_ERR_OK)
{
@ -791,8 +792,15 @@ int hg_scanner_239::read_one_image_from_usb(SANE_Image_Statu statu)
}
if (is_scanner_err_ok)
{
pop_first_image();
ret = pop_first_image();
if (ret != SCANNER_ERR_OK)
{
hg_log::log(LOG_LEVEL_FATAL, "Try ONCE pop_firt_image after 100ms ...\n");
std::this_thread::sleep_for(std::chrono::milliseconds(100));
ret = pop_first_image();
}
}
return ret;
}
int hg_scanner_239::discard_all_images(void)
@ -1358,7 +1366,7 @@ void hg_scanner_239::thread_get_dves_image(void)
if (sw.elapsed_s() > 120 && !is_auto_scan())
{
status_ = ret;
notify_ui_working_status(from_default_language(STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_OUTTIME), SANE_EVENT_ERROR, ret); // 取图通信超时
notify_ui_working_status(from_default_language(STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_OUTTIME), SANE_EVENT_ERROR, ret); // 鍙栧浘閫氫俊瓒呮椂
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "get image time out:%s\n", hg_scanner_err_name(status_));
break;
}
@ -1367,10 +1375,10 @@ void hg_scanner_239::thread_get_dves_image(void)
{
if ((get_status() & 0x03) == 0)
{
do_stop();
int err = do_stop();
is_quit_wait_paper_scan = true;//标记待纸扫描时间到了自动结束
notify_ui_working_status(from_default_language(STATU_DESC_SCANNER_ERR_DEVICE_EXIT_WAIT_SCAN), SANE_EVENT_ERROR, status_);
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "auto paper scan exit :%s\n", from_default_language(STATU_DESC_SCANNER_ERR_DEVICE_EXIT_WAIT_SCAN));
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "auto paper scan exit :%s\n", hg_scanner_err_description(err));
}
else
sw1.reset();

View File

@ -89,7 +89,7 @@ hg_scanner_300::hg_scanner_300(const char* dev_name,int pid, usb_io* io) :
{
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "hg_scanner_300(%s) constructing ...\n", hg_log::format_ptr(this).c_str());
dsp_config.value = 0;
dsp_config.params_3288.enableLed = 1; //暺䁅恕<EFBFBD>?
dsp_config.params_3288.enableLed = 1; //默认值
dsp_config.params_3288.isCorrect = 1;
int ret = initdevice();
@ -118,7 +118,7 @@ hg_scanner_300::hg_scanner_300(const char* dev_name,int pid, usb_io* io) :
firmware_sup_log_export_G300_ = year_date.compare("230430") >= 0 ? true : false;
#ifndef MAPPING_FUNCTION_IN_BASE
init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//隡睃<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//优先初始化
#endif
if (init_settings(pid_))
@ -159,11 +159,11 @@ void hg_scanner_300::thread_handle_usb_read(void)
}
//printf("usb.u32_Data = %d ret = %d\r\n",usb.u32_Data,ret);
//<EFBFBD><EFBFBD>霈曉<EFBFBD><EFBFBD>箇緵<EFBFBD>∠爾 <20>𤥁<EFBFBD><F0A4A581><EFBFBD>撘删<E69298>霈曉<E99C88>靽⊥<E99DBD><E28AA5><EFBFBD>嚗屸<E59A97><EFBFBD><E996AC><EFBFBD>啗挽憭<E68CBD><E686AD><EFBFBD><E98AB5><EFBFBD><EFBFBD>top<6F><EFBFBD><E6BBA9>𨀣迫<F0A880A3>?<3F><>隞亙<E99A9E><EFBFBD>誑 "<22>𨀣迫" 瘨<><E798A8>銝箇<E98A9D><E7AE87>煺縑<E785BA>?
//<EFBFBD><EFBFBD><EFBFBD>匧㦛<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>僎銝𥪜㨃蝥豢<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝑㚁<EFBFBD>霈曉<EFBFBD>隡𡁜<EFBFBD><EFBFBD><EFBFBD><EFBFBD>㨃蝥詨<EFBFBD>撘牐縑<EFBFBD><EFBFBD><EFBFBD><EFBFBD>隞交𦻖<EFBFBD><EFBFBD><EFBFBD>躰秤靽⊥<EFBFBD>銋见<EFBFBD>嚗䔶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>硋枂<EFBFBD><EFBFBD>?
//如果设备出现卡纸 或者双张等设备信息问题需要等到设备进行发送stop才能停止。 所以始终以 "停止" 消息为结束信号
//如果有图的情况下,并且卡纸或双张等,设备会先发送卡纸双张信息。所以接受到错误信息之后,仍需要把图像取出来。
if (ret == SCANNER_ERR_DEVICE_STOPPED)
{
status_ = !savestatus_.empty() ? savestatus_[0] : SCANNER_ERR_OK;//隞亦洵銝<EFBFBD>銝芣<EFBFBD><EFBFBD>臭蛹<EFBFBD>?
status_ = !savestatus_.empty() ? savestatus_[0] : SCANNER_ERR_OK;//以第一个消息为准
savestatus_.clear();
if (user_cancel_)
{
@ -240,7 +240,7 @@ void hg_scanner_300::thread_handle_usb_read(void)
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "%s\n", hg_scanner_err_description(status_));
break;
}
if (sw.elapsed_ms() > 30000 && img_conf_.resolution_dst != 600)//<EFBFBD>脫迫<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝滢<EFBFBD><EFBFBD>亙紡<EFBFBD>游㨃甇?
if (sw.elapsed_ms() > 30000 && img_conf_.resolution_dst != 600)//防止状态信息一直取不上来导致卡死
{
if ((img_conf_.papertype == TwSS::MaxSize || img_conf_.papertype == TwSS::USStatement) && pid_ == 0x0300 && firmware_sup_dpi_600)
{
@ -248,30 +248,30 @@ void hg_scanner_300::thread_handle_usb_read(void)
}
else
{
if (!savestatus_.empty())//隞亦洵銝<EFBFBD>銝芣<EFBFBD><EFBFBD>臭蛹<EFBFBD>?
if (!savestatus_.empty())//以第一个消息为准
{
status_ = savestatus_[0];
}
savestatus_.clear();
hg_log::log(LOG_LEVEL_WARNING, "Get Status TimeOut,get image out 30S\n");
notify_ui_working_status(hg_log::lang_load(ID_STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_OUTTIME), SANE_EVENT_ERROR, status_); // <EFBFBD>蹱𡵆瘚㗛𢥫瘞思<EFBFBD><EFBFBD>鍦䴴璊?
notify_ui_working_status(hg_log::lang_load(ID_STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_OUTTIME), SANE_EVENT_ERROR, status_); // 閸欐牕娴橀柅姘繆鐡掑懏妞?
break;
}
}
if (sw.elapsed_s() > 130)
{
if (!savestatus_.empty())//隞亦洵銝<EFBFBD>銝芣<EFBFBD><EFBFBD>臭蛹<EFBFBD>?
if (!savestatus_.empty())//以第一个消息为准
{
status_ = savestatus_[0];
}
savestatus_.clear();
hg_log::log(LOG_LEVEL_WARNING, "MaxSize TimeOut,Get Image 130s\n");
notify_ui_working_status(hg_log::lang_load(ID_STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_OUTTIME), SANE_EVENT_ERROR, status_); // <EFBFBD>蹱𡵆瘚㗛𢥫瘞思<EFBFBD><EFBFBD>鍦䴴璊?
notify_ui_working_status(hg_log::lang_load(ID_STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_OUTTIME), SANE_EVENT_ERROR, status_); // 閸欐牕娴橀柅姘繆鐡掑懏妞?
break;
}
if (ret == SCANNER_ERR_OK && usb.u32_Count > 0)
{
int totalNum = usb.u32_Count & 0x3fffffff; // 2022-08-04: <EFBFBD>澆捆Android嚗屸<EFBFBD>霈文㦛<EFBFBD><EFBFBD>之撠誩<EFBFBD><EFBFBD>?GB隞亙<E99A9E>
int totalNum = usb.u32_Count & 0x3fffffff; // 2022-08-04: 兼容Android默认图片大小均在1GB以内
VLOG_MINI_2(LOG_LEVEL_WARNING, "Get Scaner Image Size:%d bytes,Image Num[%d]\n", totalNum,img_num);
img_num++;
if (totalNum)
@ -382,7 +382,7 @@ int hg_scanner_300::do_start(void)
{
return ret;
}
if (is_devs_sleep_)//霈曉<EFBFBD><EFBFBD>函辺<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝剛繮<EFBFBD>硋𤐄隞嗆糓憭梯揖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>隞亙銁餈嗘葵<EFBFBD>唳䲮餈𥡝<EFBFBD><EFBFBD><EFBFBD><EFBFBD>雿滩挽蝵柴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>閫劐<EFBFBD>靽嗪埯嚗?
if (is_devs_sleep_)//设备在睡眠的状态当中获取固件是失败的,所以在这个地方进行标志位设置。(总感觉不保险)
{
is_devs_sleep_ = false;
set_kernelsnap_ver();
@ -807,7 +807,7 @@ int hg_scanner_300::initdevice()
if (status_ != SCANNER_ERR_DEVICE_SLEEPING)
{
set_kernelsnap_ver();
is_devs_sleep_ = false; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><E691B0><EFBCB8>𣂼<EFBFBD><F0A382BC>孵稬霈曄蔭餈躰器<E8BAB0>箔辣<E7AE94><E8BEA3>𧋦<EFBFBD>?餈䀹瓷<E480B9><EFBFBD><E58CA7>斗鱏<E69697>?
is_devs_sleep_ = false; // 睡眠唤醒 客户提前点击设置这边固件版本号 还没有做判断的
}
return status_;
}
@ -839,7 +839,7 @@ void hg_scanner_300::writedown_image_configuration(void)
// ic.hardwarecaps.is_autopaper = dsp_config_.params_dsp.is_autopaper;
ic.hardwarecaps.capturepixtype = 0; //暂无参数 获取图像类型
ic.hardwarecaps.lowpowermode = LowPowerMode::Min_None; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㺭 霈曄蔭隡𤑳<E99AA1><F0A491B3>園𡢿 銝支葵<E694AF><E891B5>㺭3399<39>芯蝙<E88AAF>?
ic.hardwarecaps.lowpowermode = LowPowerMode::Min_None; //暂无参数 设置休眠时间 两个参数3399未使用
image_configuration(ic);
}
void hg_scanner_300::printf_devconfig(setting_hardware::HGSCANCONF_3288 *d)
@ -980,7 +980,7 @@ int hg_scanner_300::get_correction_image(int inx , int dpi, int mode)
cv::Mat white_mat;
cv::Mat black_mat;;
for (size_t i = 0; i < 2; i++) //暺𤑳蒾銝<EFBFBD>韏瑚<EFBFBD>摮䀝<EFBFBD><EFBFBD>?
for (size_t i = 0; i < 2; i++) //黑白一起保存下来
{
vector<unsigned char> imagedata;
@ -1022,7 +1022,7 @@ int hg_scanner_300::get_correction_image(int inx , int dpi, int mode)
if (mat.empty())
{
VLOG_MINI_1(LOG_LEVEL_WARNING, "get_correction_image image is NULL:%d\n", image_info.info.params.status);
return SCANNER_ERR_NO_DATA; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>撘惩㦛瘝⊥<EFBFBD> <20>湔𦻖<E6B994><F0A6BB96>鈭?
return SCANNER_ERR_NO_DATA; //只要有一张图没有 直接退了
}
float f = 0.0;
@ -1055,7 +1055,7 @@ std::string hg_scanner_300::get_firmware_version()
{
char buf[20] = { 0 };
int ret = SCANNER_ERR_OK,
len = 10; //<EFBFBD>讛悅摰帋<EFBFBD><EFBFBD>踹漲銝?0 100 200 =8
len = 10; //协议定义长度为10 100 200 =8
USBCB cmd = { setting3288dsp::GET_FW_VERSION,len,0,};
{

View File

@ -84,7 +84,7 @@ hg_scanner_306::hg_scanner_306(const char* dev_name,int pid, usb_io* io) :
{
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "hg_scanner_306(%s) constructing ...\n", hg_log::format_ptr(this).c_str());
dsp_config.value = 0;
dsp_config.params_7010.enableLed = 1; //暺䁅恕<EFBFBD>?
dsp_config.params_7010.enableLed = 1; //默认值
dsp_config.params_7010.isCorrect = 1;
int ret = get_device_type(firmware_sup_device_7010);
@ -101,7 +101,7 @@ hg_scanner_306::hg_scanner_306(const char* dev_name,int pid, usb_io* io) :
}
#ifndef MAPPING_FUNCTION_IN_BASE
init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//隡睃<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//优先初始化
#endif
if (init_settings(pid_))
init_settings((jsontext1 + jsontext2 + jsontext3).c_str());
@ -136,11 +136,11 @@ void hg_scanner_306::thread_handle_usb_read(void)
}
//printf("usb.u32_Data = %d ret = %d\r\n",usb.u32_Data,ret);
//<EFBFBD><EFBFBD>霈曉<EFBFBD><EFBFBD>箇緵<EFBFBD>∠爾 <20>𤥁<EFBFBD><F0A4A581><EFBFBD>撘删<E69298>霈曉<E99C88>靽⊥<E99DBD><E28AA5><EFBFBD>嚗屸<E59A97><EFBFBD><E996AC><EFBFBD>啗挽憭<E68CBD><E686AD><EFBFBD><E98AB5><EFBFBD><EFBFBD>top<6F><EFBFBD><E6BBA9>𨀣迫<F0A880A3>?<3F><>隞亙<E99A9E><EFBFBD>誑 "<22>𨀣迫" 瘨<><E798A8>銝箇<E98A9D><E7AE87>煺縑<E785BA>?
//<EFBFBD><EFBFBD><EFBFBD>匧㦛<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>僎銝𥪜㨃蝥豢<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝑㚁<EFBFBD>霈曉<EFBFBD>隡𡁜<EFBFBD><EFBFBD><EFBFBD><EFBFBD>㨃蝥詨<EFBFBD>撘牐縑<EFBFBD><EFBFBD><EFBFBD><EFBFBD>隞交𦻖<EFBFBD><EFBFBD><EFBFBD>躰秤靽⊥<EFBFBD>銋见<EFBFBD>嚗䔶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>硋枂<EFBFBD><EFBFBD>?
//如果设备出现卡纸 或者双张等设备信息问题需要等到设备进行发送stop才能停止。 所以始终以 "停止" 消息为结束信号
//如果有图的情况下,并且卡纸或双张等,设备会先发送卡纸双张信息。所以接受到错误信息之后,仍需要把图像取出来。
if (ret == SCANNER_ERR_DEVICE_STOPPED)
{
status_ = !savestatus_.empty() ? savestatus_[0] : SCANNER_ERR_OK;//隞亦洵銝<EFBFBD>銝芣<EFBFBD><EFBFBD>臭蛹<EFBFBD>?
status_ = !savestatus_.empty() ? savestatus_[0] : SCANNER_ERR_OK;//以第一个消息为准
savestatus_.clear();
if (user_cancel_)
{
@ -217,7 +217,7 @@ void hg_scanner_306::thread_handle_usb_read(void)
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "%s\n", hg_scanner_err_description(status_));
break;
}
if (sw.elapsed_ms() > 30000 && img_conf_.resolution_dst != 600)//<EFBFBD>脫迫<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝滢<EFBFBD><EFBFBD>亙紡<EFBFBD>游㨃甇?
if (sw.elapsed_ms() > 30000 && img_conf_.resolution_dst != 600)//防止状态信息一直取不上来导致卡死
{
if ((img_conf_.papertype == TwSS::MaxSize || img_conf_.papertype == TwSS::USStatement) && pid_ == 0x0300 && firmware_sup_dpi_600)
{
@ -225,25 +225,25 @@ void hg_scanner_306::thread_handle_usb_read(void)
}
else
{
if (!savestatus_.empty())//隞亦洵銝<EFBFBD>銝芣<EFBFBD><EFBFBD>臭蛹<EFBFBD>?
if (!savestatus_.empty())//以第一个消息为准
{
status_ = savestatus_[0];
}
savestatus_.clear();
hg_log::log(LOG_LEVEL_WARNING, "Get Status TimeOut,get image out 30S\n");
notify_ui_working_status(hg_log::lang_load(ID_STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_OUTTIME), SANE_EVENT_ERROR, status_); // <EFBFBD>蹱𡵆瘚㗛𢥫瘞思<EFBFBD><EFBFBD>鍦䴴璊?
notify_ui_working_status(hg_log::lang_load(ID_STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_OUTTIME), SANE_EVENT_ERROR, status_); // 鍙栧浘閫氫俊瓒呮椂
break;
}
}
if (sw.elapsed_s() > 130)
{
if (!savestatus_.empty())//隞亦洵銝<EFBFBD>銝芣<EFBFBD><EFBFBD>臭蛹<EFBFBD>?
if (!savestatus_.empty())//以第一个消息为准
{
status_ = savestatus_[0];
}
savestatus_.clear();
hg_log::log(LOG_LEVEL_WARNING, "MaxSize TimeOut,Get Image 130s\n");
notify_ui_working_status(hg_log::lang_load(ID_STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_OUTTIME), SANE_EVENT_ERROR, status_); // <EFBFBD>蹱𡵆瘚㗛𢥫瘞思<EFBFBD><EFBFBD>鍦䴴璊?
notify_ui_working_status(hg_log::lang_load(ID_STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_OUTTIME), SANE_EVENT_ERROR, status_); // 閸欐牕娴橀柅姘繆鐡掑懏妞?
break;
}
if (ret == SCANNER_ERR_OK && usb.u32_Count > 0)
@ -338,7 +338,7 @@ int hg_scanner_306::do_start(void)
{
return ret;
}
if (is_devs_sleep_)//霈曉<EFBFBD><EFBFBD>函辺<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝剛繮<EFBFBD>硋𤐄隞嗆糓憭梯揖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>隞亙銁餈嗘葵<EFBFBD>唳䲮餈𥡝<EFBFBD><EFBFBD><EFBFBD><EFBFBD>雿滩挽蝵柴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>閫劐<EFBFBD>靽嗪埯嚗?
if (is_devs_sleep_)//设备在睡眠的状态当中获取固件是失败的,所以在这个地方进行标志位设置。(总感觉不保险)
{
is_devs_sleep_ = false;
set_kernelsnap_ver();
@ -763,7 +763,7 @@ int hg_scanner_306::initdevice()
if (status_ != SCANNER_ERR_DEVICE_SLEEPING)
{
set_kernelsnap_ver();
is_devs_sleep_ = false; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><E691B0><EFBCB8>𣂼<EFBFBD><F0A382BC>孵稬霈曄蔭餈躰器<E8BAB0>箔辣<E7AE94><E8BEA3>𧋦<EFBFBD>?餈䀹瓷<E480B9><EFBFBD><E58CA7>斗鱏<E69697>?
is_devs_sleep_ = false; // 睡眠唤醒 客户提前点击设置这边固件版本号 还没有做判断的
}
return SCANNER_ERR_OK;
}
@ -795,7 +795,7 @@ void hg_scanner_306::writedown_image_configuration(void)
// ic.hardwarecaps.is_autopaper = dsp_config_.params_dsp.is_autopaper;
ic.hardwarecaps.capturepixtype = 0; //暂无参数 获取图像类型
ic.hardwarecaps.lowpowermode = LowPowerMode::Min_None; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㺭 霈曄蔭隡𤑳<E99AA1><F0A491B3>園𡢿 銝支葵<E694AF><E891B5>㺭3399<39>芯蝙<E88AAF>?
ic.hardwarecaps.lowpowermode = LowPowerMode::Min_None; //暂无参数 设置休眠时间 两个参数3399未使用
image_configuration(ic);
}
void hg_scanner_306::printf_devconfig(setting_hardware::HGSCANCONF_7010 *d)
@ -875,7 +875,7 @@ int hg_scanner_306::get_correction_image(int inx , int dpi, int mode)
cv::Mat white_mat;
cv::Mat black_mat;;
for (size_t i = 0; i < 2; i++) //暺𤑳蒾銝<EFBFBD>韏瑚<EFBFBD>摮䀝<EFBFBD><EFBFBD>?
for (size_t i = 0; i < 2; i++) //黑白一起保存下来
{
vector<unsigned char> imagedata;
@ -913,7 +913,7 @@ int hg_scanner_306::get_correction_image(int inx , int dpi, int mode)
if (mat.empty())
{
VLOG_MINI_1(LOG_LEVEL_WARNING, "get_correction_image image is NULL:%d\n", image_info.info.params.status);
return SCANNER_ERR_NO_DATA; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>撘惩㦛瘝⊥<EFBFBD> <20>湔𦻖<E6B994><F0A6BB96>鈭?
return SCANNER_ERR_NO_DATA; //只要有一张图没有 直接退了
}
float f = 0.0;
@ -939,7 +939,7 @@ std::string hg_scanner_306::get_firmware_version()
{
char buf[20] = { 0 };
int ret = SCANNER_ERR_OK,
len = 10; //<EFBFBD>讛悅摰帋<EFBFBD><EFBFBD>踹漲銝?0 100 200 =8
len = 10; //协议定义长度为10 100 200 =8
USBCB cmd = { setting3288dsp::GET_FW_VERSION,len,0,};
{
@ -1226,13 +1226,13 @@ int hg_scanner_306::set_scan_lock_check_val(string str)
}
//#enum scanner_err
//#{
//# SCANNER_ERR_OK = 0, //霈曉<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
//# SCANNER_ERR_OK = 0, //设备正常状态
//# SCANNER_ERR_SLEEP, 1 //设备处于休眠当中
//# SCANNER_ERR_UPDATE_OK, 2 //霈曉<EFBFBD><EFBFBD>湔鰵嚗𡁏<EFBFBD><EFBFBD>?
//# SCANNER_ERR_UPDATE_OK, 2 //设备更新:成功
//# SCANNER_ERR_UPDATE_UPDATAING, 3 //设备更新:进行中
//# SCANNER_ERR_UPDATE_CHECK_VAL_ERROR, 4 //霈曉<EFBFBD><EFBFBD>湔鰵嚗𡁏嵗撉峕<EFBFBD>瘚钅<EFBFBD>霂?
//# SCANNER_ERR_UPDATE_CHECK_FILE_LOST, 5 //霈曉<EFBFBD><EFBFBD>湔鰵嚗𡁏<EFBFBD>隞嗡腺憭?
//# SCANNER_ERR_UPDATE_UNZIP_FAIL, 6 //霈曉<EFBFBD><EFBFBD>湔鰵嚗朞圾<EFBFBD>见仃韐?
//# SCANNER_ERR_UPDATE_CHECK_VAL_ERROR, 4 //设备更新:校验检测错误
//# SCANNER_ERR_UPDATE_CHECK_FILE_LOST, 5 //设备更新:文件丢失
//# SCANNER_ERR_UPDATE_UNZIP_FAIL, 6 //设备更新:解压失败
//#};
int hg_scanner_306::set_firmware_upgrade(std::string str)
{

View File

@ -758,13 +758,13 @@ namespace hg_imgproc
}
return SCANNER_ERR_OK;
}
int multi_out(int out_type)
int multi_out(int out_type, int bw_threshold)
{
std::vector<cv::Mat> mats(mats_);
std::vector<cv::Mat> mat;
mats_.clear();
IMageMulti output(out_type);
IMageMulti output(out_type, bw_threshold);
for(size_t i = 0;i < mats.size();i++)
{
@ -1973,9 +1973,9 @@ namespace hg_imgproc
{
return ((imgproc*)himg)->fadeback();
}
int multi_out(HIMGPRC himg,int out_type)
int multi_out(HIMGPRC himg, int out_type, int bw_threshold)
{
return ((imgproc*)himg)->multi_out(out_type);
return ((imgproc*)himg)->multi_out(out_type, bw_threshold);
}
int multi_out_red(HIMGPRC himg)
{

View File

@ -182,7 +182,7 @@ namespace hg_imgproc
//拆分
int split(HIMGPRC himg,int split3399);
int fadeback(HIMGPRC himg);
int multi_out(HIMGPRC himg,int out_type);
int multi_out(HIMGPRC himg,int out_type, int bw_threshold);
int multi_out_red(HIMGPRC himg);
int auto_matic_color(HIMGPRC himg,int color_type);
int auto_crop(HIMGPRC himg, float dpi);

View File

@ -839,6 +839,7 @@ scanner_err hg_scanner_mgr::hg_scanner_close(scanner_handle h, bool force)
}
}
SCAN_PTR(h)->stop();
SCAN_PTR(h)->close(force);
delete SCAN_PTR(h);

View File

@ -264,6 +264,13 @@ extern "C"
return true;
}
static bool save_dir_files(const char* path_file, void* param)
{
((std::vector<std::string>*)param)->push_back(path_file);
return true;
}
#if defined(WIN32) || defined(_WIN64)
static std::string u2a(const wchar_t* u, UINT cp = CP_ACP)
{
@ -287,25 +294,56 @@ extern "C"
static int enum_files(const char* dir, bool recursive, bool(*found_file)(const char* path_file, void* param), void* param)
{
int ret = 0;
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
MODULEENTRY32W pei = { 0 };
if (h == INVALID_HANDLE_VALUE)
ret = GetLastError();
if (!dir || *dir == 0)
{
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
MODULEENTRY32W pei = { 0 };
if (h == INVALID_HANDLE_VALUE)
ret = GetLastError();
else
{
pei.dwSize = sizeof(pei);
if (Module32FirstW(h, &pei))
{
do
{
std::string ansi(u2a(pei.szExePath));
if (!found_file(ansi.c_str(), param))
break;
pei.dwSize = sizeof(pei);
} while (Module32NextW(h, &pei));
}
CloseHandle(h);
}
}
else
{
pei.dwSize = sizeof(pei);
if (Module32FirstW(h, &pei))
WIN32_FIND_DATAA wfd = { 0 };
HANDLE h = FindFirstFileA((std::string(dir) + "\\*").c_str(), &wfd);
if (h == INVALID_HANDLE_VALUE)
ret = GetLastError();
else
{
do
{
std::string ansi(u2a(pei.szExePath));
if (!found_file(ansi.c_str(), param))
if (strcmp(wfd.cFileName, ".") == 0 || strcmp(wfd.cFileName, "..") == 0)
continue;
if (!found_file((std::string(dir) + "\\" + wfd.cFileName).c_str(), param))
{
ret = ECANCELED;
break;
pei.dwSize = sizeof(pei);
} while (Module32NextW(h, &pei));
}
if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && recursive)
{
ret = enum_files((std::string(dir) + "\\" + wfd.cFileName).c_str(), recursive, found_file, param);
if (ret == ECANCELED)
break;
}
} while (FindNextFileA(h, &wfd));
FindClose(h);
}
CloseHandle(h);
}
return ret;
@ -539,6 +577,10 @@ extern "C"
{
return MKDIR(fodler, S_IREAD | S_IWRITE | S_IEXEC) == 0 || errno == EEXIST;
}
void get_foler_files(const char* folder, std::vector<std::string>& files, bool recursive)
{
enum_files(folder, recursive, save_dir_files, &files);
}
std::string ini_get(const char* app, const char* key)
{
return ini_.get(app, key);

View File

@ -6,6 +6,8 @@
#pragma once
#include <string>
#include <vector>
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include "lang/app_language.h"
#if defined(WIN32) || defined(_WIN64)
@ -64,6 +66,7 @@ extern "C"
unsigned long long available_memory(void);
void str_tolower(std::string& str);
bool create_folder(const char* fodler);
void get_foler_files(const char* folder, std::vector<std::string>& files, bool recursive = false);
std::string ini_get(const char* app, const char* key);
void ini_set(const char* app, const char* key, const char* val);

View File

@ -240,6 +240,8 @@ extern "C"
RETURN_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED);
RETURN_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM);
RETURN_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM);
RETURN_IF(err, SCANNER_ERR_IMAGE_PROC_FATAL);
RETURN_IF(err, SCANNER_ERR_NOT_OPEN);
RETURN_IF(err, SCANNER_ERR_NOT_START);
RETURN_IF(err, SCANNER_ERR_NOT_ANY_MORE);
@ -317,6 +319,8 @@ extern "C"
RETURN_DESC_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED);
RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM);
RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM);
RETURN_DESC_IF(err, SCANNER_ERR_IMAGE_PROC_FATAL);
RETURN_DESC_IF(err, SCANNER_ERR_NOT_OPEN);
RETURN_DESC_IF(err, SCANNER_ERR_NOT_START);
RETURN_DESC_IF(err, SCANNER_ERR_NOT_ANY_MORE);

View File

@ -1688,6 +1688,8 @@ SANE_Status hg_sane_middleware::start(SANE_Handle h, void* async_event)
scanner_handle hs = find_openning_device(h);
scanner_err err = SCANNER_ERR_INVALID_PARAMETER;
LOG_INFO(LOG_LEVEL_ALL, "sane_start ...\n");
if(hs)
err = hg_scanner_start(hs, async_event, -1);
@ -2589,8 +2591,6 @@ extern "C" { // avoid compiler exporting name in C++ style !!!
}
SANE_Status inner_sane_start(SANE_Handle handle)
{
LOG_INFO(LOG_LEVEL_ALL, "sane_start\n");
return hg_sane_middleware::instance()->start(handle, NULL);
}
SANE_Status inner_sane_read(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length)