Mercurial > hg > orthanc-stone
comparison Framework/Radiography/RadiographyScene.cpp @ 483:29fc066b6f65 am-touch-events
Export now accepts Json::Value
author | am@osimis.io |
---|---|
date | Fri, 15 Feb 2019 10:39:23 +0100 |
parents | 159a465e27bd |
children | 7bf001b9d244 |
comparison
equal
deleted
inserted
replaced
481:159a465e27bd | 483:29fc066b6f65 |
---|---|
585 | 585 |
586 return rendered.release(); | 586 return rendered.release(); |
587 } | 587 } |
588 | 588 |
589 | 589 |
590 void RadiographyScene::ExportDicom(OrthancApiClient& orthanc, | |
591 const Json::Value& dicomTags, | |
592 const std::string& parentOrthancId, | |
593 double pixelSpacingX, | |
594 double pixelSpacingY, | |
595 bool invert, | |
596 ImageInterpolation interpolation, | |
597 bool usePam) | |
598 { | |
599 Json::Value createDicomRequestContent; | |
600 | |
601 std::auto_ptr<Orthanc::Image> rendered(ExportToImage(pixelSpacingX, pixelSpacingY, interpolation)); // note: we don't invert the image in the pixels data because we'll set the PhotometricDisplayMode correctly in the DICOM tags | |
602 | |
603 std::string base64; | |
604 | |
605 { | |
606 std::string content; | |
607 | |
608 if (usePam) | |
609 { | |
610 Orthanc::PamWriter writer; | |
611 writer.WriteToMemory(content, *rendered); | |
612 } | |
613 else | |
614 { | |
615 Orthanc::PngWriter writer; | |
616 writer.WriteToMemory(content, *rendered); | |
617 } | |
618 | |
619 Orthanc::Toolbox::EncodeBase64(base64, content); | |
620 } | |
621 | |
622 createDicomRequestContent["Tags"] = dicomTags; | |
623 | |
624 PhotometricDisplayMode photometricMode = GetPreferredPhotomotricDisplayMode(); | |
625 if ((invert && photometricMode != PhotometricDisplayMode_Monochrome2) || | |
626 (!invert && photometricMode == PhotometricDisplayMode_Monochrome1)) | |
627 { | |
628 createDicomRequestContent["Tags"]["PhotometricInterpretation"] = "MONOCHROME1"; | |
629 } | |
630 else | |
631 { | |
632 createDicomRequestContent["Tags"]["PhotometricInterpretation"] = "MONOCHROME2"; | |
633 } | |
634 | |
635 // WARNING: The order of PixelSpacing is Y/X. We use "%0.8f" to | |
636 // avoid floating-point numbers to grow over 16 characters, | |
637 // which would be invalid according to DICOM standard | |
638 // ("dciodvfy" would complain). | |
639 char buf[32]; | |
640 sprintf(buf, "%0.8f\\%0.8f", pixelSpacingY, pixelSpacingX); | |
641 | |
642 createDicomRequestContent["Tags"]["PixelSpacing"] = buf; | |
643 | |
644 float center, width; | |
645 if (GetWindowing(center, width)) | |
646 { | |
647 createDicomRequestContent["Tags"]["WindowCenter"] = | |
648 boost::lexical_cast<std::string>(boost::math::iround(center)); | |
649 | |
650 createDicomRequestContent["Tags"]["WindowWidth"] = | |
651 boost::lexical_cast<std::string>(boost::math::iround(width)); | |
652 } | |
653 | |
654 | |
655 // This is Data URI scheme: https://en.wikipedia.org/wiki/Data_URI_scheme | |
656 createDicomRequestContent["Content"] = ("data:" + | |
657 std::string(usePam ? Orthanc::MIME_PAM : Orthanc::MIME_PNG) + | |
658 ";base64," + base64); | |
659 | |
660 if (!parentOrthancId.empty()) | |
661 { | |
662 createDicomRequestContent["Parent"] = parentOrthancId; | |
663 } | |
664 | |
665 orthanc.PostJsonAsyncExpectJson( | |
666 "/tools/create-dicom", createDicomRequestContent, | |
667 new Callable<RadiographyScene, OrthancApiClient::JsonResponseReadyMessage> | |
668 (*this, &RadiographyScene::OnDicomExported), | |
669 NULL, NULL); | |
670 | |
671 } | |
672 | |
673 | |
590 // Export using PAM is faster than using PNG, but requires Orthanc | 674 // Export using PAM is faster than using PNG, but requires Orthanc |
591 // core >= 1.4.3 | 675 // core >= 1.4.3 |
592 void RadiographyScene::ExportDicom(OrthancApiClient& orthanc, | 676 void RadiographyScene::ExportDicom(OrthancApiClient& orthanc, |
593 const Orthanc::DicomMap& dicom, | 677 const Orthanc::DicomMap& dicom, |
594 const std::string& parentOrthancId, | 678 const std::string& parentOrthancId, |
596 double pixelSpacingY, | 680 double pixelSpacingY, |
597 bool invert, | 681 bool invert, |
598 ImageInterpolation interpolation, | 682 ImageInterpolation interpolation, |
599 bool usePam) | 683 bool usePam) |
600 { | 684 { |
601 Json::Value createDicomRequestContent; | |
602 | |
603 std::auto_ptr<Orthanc::Image> rendered(ExportToImage(pixelSpacingX, pixelSpacingY, interpolation)); // note: we don't invert the image in the pixels data because we'll set the PhotometricDisplayMode correctly in the DICOM tags | |
604 | |
605 std::string base64; | |
606 | |
607 { | |
608 std::string content; | |
609 | |
610 if (usePam) | |
611 { | |
612 Orthanc::PamWriter writer; | |
613 writer.WriteToMemory(content, *rendered); | |
614 } | |
615 else | |
616 { | |
617 Orthanc::PngWriter writer; | |
618 writer.WriteToMemory(content, *rendered); | |
619 } | |
620 | |
621 Orthanc::Toolbox::EncodeBase64(base64, content); | |
622 } | |
623 | |
624 std::set<Orthanc::DicomTag> tags; | 685 std::set<Orthanc::DicomTag> tags; |
625 dicom.GetTags(tags); | 686 dicom.GetTags(tags); |
626 | 687 |
627 createDicomRequestContent["Tags"] = Json::objectValue; | 688 Json::Value jsonTags = Json::objectValue; |
628 | 689 |
629 for (std::set<Orthanc::DicomTag>::const_iterator | 690 for (std::set<Orthanc::DicomTag>::const_iterator |
630 tag = tags.begin(); tag != tags.end(); ++tag) | 691 tag = tags.begin(); tag != tags.end(); ++tag) |
631 { | 692 { |
632 const Orthanc::DicomValue& value = dicom.GetValue(*tag); | 693 const Orthanc::DicomValue& value = dicom.GetValue(*tag); |
633 if (!value.IsNull() && | 694 if (!value.IsNull() && |
634 !value.IsBinary()) | 695 !value.IsBinary()) |
635 { | 696 { |
636 createDicomRequestContent["Tags"][tag->Format()] = value.GetContent(); | 697 jsonTags[tag->Format()] = value.GetContent(); |
637 } | 698 } |
638 } | 699 } |
639 | 700 |
640 PhotometricDisplayMode photometricMode = GetPreferredPhotomotricDisplayMode(); | 701 ExportDicom(orthanc, jsonTags, parentOrthancId, pixelSpacingX, pixelSpacingY, invert, interpolation, usePam); |
641 if ((invert && photometricMode != PhotometricDisplayMode_Monochrome2) || | |
642 (!invert && photometricMode == PhotometricDisplayMode_Monochrome1)) | |
643 { | |
644 createDicomRequestContent["Tags"][Orthanc::DICOM_TAG_PHOTOMETRIC_INTERPRETATION.Format()] = "MONOCHROME1"; | |
645 } | |
646 else | |
647 { | |
648 createDicomRequestContent["Tags"][Orthanc::DICOM_TAG_PHOTOMETRIC_INTERPRETATION.Format()] = "MONOCHROME2"; | |
649 } | |
650 | |
651 // WARNING: The order of PixelSpacing is Y/X. We use "%0.8f" to | |
652 // avoid floating-point numbers to grow over 16 characters, | |
653 // which would be invalid according to DICOM standard | |
654 // ("dciodvfy" would complain). | |
655 char buf[32]; | |
656 sprintf(buf, "%0.8f\\%0.8f", pixelSpacingY, pixelSpacingX); | |
657 | |
658 createDicomRequestContent["Tags"][Orthanc::DICOM_TAG_PIXEL_SPACING.Format()] = buf; | |
659 | |
660 float center, width; | |
661 if (GetWindowing(center, width)) | |
662 { | |
663 createDicomRequestContent["Tags"][Orthanc::DICOM_TAG_WINDOW_CENTER.Format()] = | |
664 boost::lexical_cast<std::string>(boost::math::iround(center)); | |
665 | |
666 createDicomRequestContent["Tags"][Orthanc::DICOM_TAG_WINDOW_WIDTH.Format()] = | |
667 boost::lexical_cast<std::string>(boost::math::iround(width)); | |
668 } | |
669 | |
670 | |
671 // This is Data URI scheme: https://en.wikipedia.org/wiki/Data_URI_scheme | |
672 createDicomRequestContent["Content"] = ("data:" + | |
673 std::string(usePam ? Orthanc::MIME_PAM : Orthanc::MIME_PNG) + | |
674 ";base64," + base64); | |
675 | |
676 if (!parentOrthancId.empty()) | |
677 { | |
678 createDicomRequestContent["Parent"] = parentOrthancId; | |
679 } | |
680 | |
681 orthanc.PostJsonAsyncExpectJson( | |
682 "/tools/create-dicom", createDicomRequestContent, | |
683 new Callable<RadiographyScene, OrthancApiClient::JsonResponseReadyMessage> | |
684 (*this, &RadiographyScene::OnDicomExported), | |
685 NULL, NULL); | |
686 } | 702 } |
687 | 703 |
688 void RadiographyScene::OnDicomExported(const OrthancApiClient::JsonResponseReadyMessage& message) | 704 void RadiographyScene::OnDicomExported(const OrthancApiClient::JsonResponseReadyMessage& message) |
689 { | 705 { |
690 LOG(INFO) << "DICOM export was successful: " | 706 LOG(INFO) << "DICOM export was successful: " |