|
5 | 5 | #include <structmember.h> |
6 | 6 | #include "DynamsoftDocumentNormalizer.h" |
7 | 7 | #include "document_result.h" |
| 8 | +#include "normalized_image.h" |
8 | 9 | #include <thread> |
9 | 10 | #include <condition_variable> |
10 | 11 | #include <mutex> |
@@ -399,12 +400,149 @@ static PyObject *setParameters(PyObject *obj, PyObject *args) |
399 | 400 | return Py_BuildValue("i", ret); |
400 | 401 | } |
401 | 402 |
|
| 403 | +PyObject *createNormalizedImage(ImageData *imageData) |
| 404 | +{ |
| 405 | + NormalizedImage *ni = PyObject_New(NormalizedImage, &NormalizedImageType); |
| 406 | + ni->bytearray = PyByteArray_FromStringAndSize((const char *)imageData->bytes, imageData->bytesLength); |
| 407 | + ni->length = Py_BuildValue("i", imageData->bytesLength); |
| 408 | + ni->width = Py_BuildValue("i", imageData->width); |
| 409 | + ni->height = Py_BuildValue("i", imageData->height); |
| 410 | + ni->stride = Py_BuildValue("i", imageData->stride); |
| 411 | + ni->format = Py_BuildValue("i", imageData->format); |
| 412 | + return (PyObject *)ni; |
| 413 | +} |
| 414 | +/** |
| 415 | + * Normalize the document. |
| 416 | + * |
| 417 | + * @param string filePath |
| 418 | + * |
| 419 | + * @return Normalized document image |
| 420 | + */ |
| 421 | +static PyObject *normalizeFile(PyObject *obj, PyObject *args) |
| 422 | +{ |
| 423 | + DynamsoftDocumentScanner *self = (DynamsoftDocumentScanner *)obj; |
| 424 | + |
| 425 | + char *pFileName; |
| 426 | + int x1, y1, x2, y2, x3, y3, x4, y4; |
| 427 | + if (!PyArg_ParseTuple(args, "siiiiiiii", &pFileName, &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) |
| 428 | + return NULL; |
| 429 | + |
| 430 | + Quadrilateral quad; |
| 431 | + quad.points[0].coordinate[0] = x1; |
| 432 | + quad.points[0].coordinate[1] = y1; |
| 433 | + quad.points[1].coordinate[0] = x2; |
| 434 | + quad.points[1].coordinate[1] = y2; |
| 435 | + quad.points[2].coordinate[0] = x3; |
| 436 | + quad.points[2].coordinate[1] = y3; |
| 437 | + quad.points[3].coordinate[0] = x4; |
| 438 | + quad.points[3].coordinate[1] = y4; |
| 439 | + |
| 440 | + NormalizedImageResult* normalizedResult = NULL; |
| 441 | + int errorCode = DDN_NormalizeFile(self->handler, pFileName, "", &quad, &normalizedResult); |
| 442 | + if (errorCode != DM_OK) |
| 443 | + printf("%s\r\n", DC_GetErrorString(errorCode)); |
| 444 | + |
| 445 | + ImageData *imageData = normalizedResult->image; |
| 446 | + |
| 447 | + PyObject *normalizedImage = createNormalizedImage(imageData); |
| 448 | + |
| 449 | + if (normalizedResult != NULL) |
| 450 | + DDN_FreeNormalizedImageResult(&normalizedResult); |
| 451 | + |
| 452 | + return normalizedImage; |
| 453 | +} |
| 454 | + |
| 455 | +/** |
| 456 | + * Normalize the document. |
| 457 | + * |
| 458 | + * @param Mat image |
| 459 | + * |
| 460 | + * @return Normalized document image |
| 461 | + */ |
| 462 | +static PyObject *normalizeBuffer(PyObject *obj, PyObject *args) |
| 463 | +{ |
| 464 | + DynamsoftDocumentScanner *self = (DynamsoftDocumentScanner *)obj; |
| 465 | + |
| 466 | + PyObject *o; |
| 467 | + int x1, y1, x2, y2, x3, y3, x4, y4; |
| 468 | + if (!PyArg_ParseTuple(args, "Oiiiiiiii", &o, &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) |
| 469 | + return NULL; |
| 470 | + |
| 471 | + Py_buffer *view; |
| 472 | + int nd; |
| 473 | + PyObject *memoryview = PyMemoryView_FromObject(o); |
| 474 | + if (memoryview == NULL) |
| 475 | + { |
| 476 | + PyErr_Clear(); |
| 477 | + return NULL; |
| 478 | + } |
| 479 | + |
| 480 | + view = PyMemoryView_GET_BUFFER(memoryview); |
| 481 | + char *buffer = (char *)view->buf; |
| 482 | + nd = view->ndim; |
| 483 | + int len = view->len; |
| 484 | + int stride = view->strides[0]; |
| 485 | + int width = view->strides[0] / view->strides[1]; |
| 486 | + int height = len / stride; |
| 487 | + |
| 488 | + ImagePixelFormat format = IPF_RGB_888; |
| 489 | + |
| 490 | + if (width == stride) |
| 491 | + { |
| 492 | + format = IPF_GRAYSCALED; |
| 493 | + } |
| 494 | + else if (width * 3 == stride) |
| 495 | + { |
| 496 | + format = IPF_RGB_888; |
| 497 | + } |
| 498 | + else if (width * 4 == stride) |
| 499 | + { |
| 500 | + format = IPF_ARGB_8888; |
| 501 | + } |
| 502 | + |
| 503 | + ImageData data; |
| 504 | + data.bytes = (unsigned char *)buffer; |
| 505 | + data.width = width; |
| 506 | + data.height = height; |
| 507 | + data.stride = stride; |
| 508 | + data.format = format; |
| 509 | + data.bytesLength = len; |
| 510 | + |
| 511 | + Quadrilateral quad; |
| 512 | + quad.points[0].coordinate[0] = x1; |
| 513 | + quad.points[0].coordinate[1] = y1; |
| 514 | + quad.points[1].coordinate[0] = x2; |
| 515 | + quad.points[1].coordinate[1] = y2; |
| 516 | + quad.points[2].coordinate[0] = x3; |
| 517 | + quad.points[2].coordinate[1] = y3; |
| 518 | + quad.points[3].coordinate[0] = x4; |
| 519 | + quad.points[3].coordinate[1] = y4; |
| 520 | + |
| 521 | + NormalizedImageResult* normalizedResult = NULL; |
| 522 | + int errorCode = DDN_NormalizeBuffer(self->handler, &data, "", &quad, &normalizedResult); |
| 523 | + if (errorCode != DM_OK) |
| 524 | + printf("%s\r\n", DC_GetErrorString(errorCode)); |
| 525 | + |
| 526 | + ImageData *imageData = normalizedResult->image; |
| 527 | + |
| 528 | + PyObject *normalizedImage = createNormalizedImage(imageData); |
| 529 | + |
| 530 | + if (normalizedResult != NULL) |
| 531 | + DDN_FreeNormalizedImageResult(&normalizedResult); |
| 532 | + |
| 533 | + Py_DECREF(memoryview); |
| 534 | + |
| 535 | + return normalizedImage; |
| 536 | +} |
| 537 | + |
402 | 538 | static PyMethodDef instance_methods[] = { |
403 | 539 | {"decodeFile", decodeFile, METH_VARARGS, NULL}, |
404 | 540 | {"decodeMat", decodeMat, METH_VARARGS, NULL}, |
405 | 541 | {"addAsyncListener", addAsyncListener, METH_VARARGS, NULL}, |
406 | 542 | {"decodeMatAsync", decodeMatAsync, METH_VARARGS, NULL}, |
407 | 543 | {"setParameters", setParameters, METH_VARARGS, NULL}, |
| 544 | + {"normalizeFile", normalizeFile, METH_VARARGS, NULL}, |
| 545 | + {"normalizeBuffer", normalizeBuffer, METH_VARARGS, NULL}, |
408 | 546 | {NULL, NULL, 0, NULL} |
409 | 547 | }; |
410 | 548 |
|
|
0 commit comments