GDCM library cannot read dicom file in C# - c#

I tried to read a DICOM file using GDCM library using this code :
gdcm.ImageReader imagereader = new gdcm.ImageReader();
imagereader.SetFileName(#"E:\sample_success.dcm");
if (!imagereader.Read()) throw new Exception("Cannot read dicom file!");
For "sample_success.dcm" file, I can read the file just fine (sample_success.png).
But using "sample_failed.dcm" file, GDCM throws exception because it couldn't read it. I tried to open the file using other DICOM viewer such as Radiant and it worked. Is there something wrong with my GDCM build? Why it cannot read it?
I use GDCM 2.6.5. Please find both samples here.

You're file contains garbage (bunch of binary 0) after offset 0x1480aa (somewhere in the Pixel Data attribute). What did you expect from a toolkit if not report properly an error ?
By design GDCM will still load whatever it can until the error. So if you remove your new Exception in your code, you can decide (for example) to pass the imagereader.GetFile() to a gdcm::Writer and rewrite the file as clean DICOM.
As a side note I do not have access to Radiant software but I find it very odd that it does not indicate an error in that case.
I've checked with DCMTK and dicom3tools they all report a parsing issue.
Using the gdcm command line tool you can almost rewrite the file clean using:
$ gdcmconv -I sample_failed.dcm sample_failed_correct.dcm
Because your input dataset is invalid, GDCM (falsely) believe to see an attribute, you can remove it using:
$ gdcmanon --dumb --remove 0,0 sample_failed_correct.dcm sample_failed_correct_clean.dcm
And then:
$ gdcminfo sample_failed_correct.dcm
MediaStorage is 1.2.840.10008.5.1.4.1.1.3.1 [Ultrasound Multi-frame Image Storage]
TransferSyntax is 1.2.840.10008.1.2.4.50 [JPEG Baseline (Process 1): Default Transfer Syntax for Lossy JPEG 8 Bit Image Compression]
NumberOfDimensions: 3
Dimensions: (800,600,21)
SamplesPerPixel :3
BitsAllocated :8
BitsStored :8
HighBit :7
PixelRepresentation:0
ScalarType found :UINT8
PhotometricInterpretation: YBR_FULL_422
PlanarConfiguration: 0
TransferSyntax: 1.2.840.10008.1.2.4.50
Origin: (0,0,0)
Spacing: (0.0106324,0.0106324,1)
DirectionCosines: (1,0,0,0,1,0)
Rescale Intercept/Slope: (0,1)
Orientation Label: AXIAL
Which is valid with the number of Fragments in the Pixel Data:
$ gdcmdump sample_failed_correct.dcm | grep Item | grep "ff.d8" | wc
21 126 2856

Related

Wkhtmltopdf not supported the --allow command

I'm using wkhtmltopdf for creating HTML to PDF. It's working fine but for some additional requirements in the pdf, I have to add the background image/watermark on every page.
I go through this link wkhtmltopdf they mention a few commands like below.
--allow <path> Allow the file or files from the specified folder to be loaded (repeatable)
--background Do print background (default)
Is there any sequence issue in the below command argument? Here is my command argument.
--page-size A4 --footer-html http://localhost:49955/PDFExport/FooterUrl
--footer-left "Printed On 11/6/2022"
--footer-right "Page [page] of [topage]"
--footer-font-size "7"
--header-spacing 5
--margin-top 5mm
--margin-left 0mm
--margin-right 0mm --outline-depth 4
--background http://localhost:49955/PDFExport/BackgroundURL
--enable-local-file-access --allow "F:\bg-overlay.jpg"
"https://wkhtmltopdf.org/usage/wkhtmltopdf.txt" "F:\TestBackground.pdf"
Here you can see how PDF looks -> OutPut link
I'm not able to perform the below command. Let me know what I missed in the command.
--background
--enable-local-file-access
--allow

Insert OLE Object into MS Word Document and keep the underlying format WMF intact

I am trying to replicate the following method in C# Word interop (NetOffice)
Selection.PasteSpecial Link:=True, DataType:=wdPasteMetafilePicture, _
Placement:=wdInLine, DisplayAsIcon:=False
I am saying "replicate" since I don't want to actually use the PasteSpecial method, since I need to update many fields of type link in one go, and don't like to communicate with excel by relying on copy and paste.
I already have the following code that does mostly what I want but has some issues that I am not able to overcome.
Selection.InlineShapes.AddOLEObject ("Excel.Sheet.12", fileName + $"!{label}", true)
This method fails with an error message
Word is unable to create a link to the object you specified. Please insert the object directly into your file without creating a link
I am only getting this error message, if and only if I use a network drive or unc path with a label.
eg.
T:\TestFile.xlsx!Sheet1!TestRange
T:\TestFile.xlsx!Sheet1!R1C1:R2C2
//notice that T is a network drive and not a local drive
\\TestShare\TestFile.xlsx!Sheet1!TestRange
\\TestShare\TestFile.xlsx!Sheet1!R1C1:R2C2
If I dont use the label
eg.
T:\TestFile.xlsx
T:\TestFile.xlsx
//notice that T is a network drive and not a local drive
\\TestShare\TestFile.xlsx
\\TestShare\TestFile.xlsx
or a local drive eg. C: (with or without label)
C:\TestFile.xlsx
C:\TestFile.xlsx
C:\TestFile.xlsx!Sheet1!TestRange
C:\TestFile.xlsx!Sheet1!R1C1:R2C2
everything works fine.
So, only the combination network drive or unc + a label produces that error message.
I thought, okay no problem I already know how to change the path and label of the produced field and wrote the following code to include the label in a second step.
var inlineShape = Selection.InlineShapes.AddOLEObject("Excel.Sheet.12", fileName, true);
field = inlineShape.Field;
if (!string.IsNullOrEmpty(label))
{
var fieldCode = field.Code.Text;
//replace the produced empty label "" with the label I desire eg. "Sheet1!R1C1:R2C2"
fieldCode = fieldCode.Replace(" \"\" ", $" \"{label}\"");
//write the updated fieldcode back to the field
field.Code.Text = fieldCode;
//update the field
field.Update();
}
BUT this solution, changes the underlying format of the image from WMF (Windows Meta File) to EMF (Enhanced Meta File), but I need it to be stored in the WMF format, since Office 2010 doesn't render EMF correctly.
To get the underlying file, I rename my docx to zip and extract it to look into the word\media directory.
PasteSpecial doesn't throw that error, and produces that desired WMF format, but I can't seem to 100% replicate the routine that happens while PasteSpecial.
As I side note, I don't want to have png or bmp either, since those are generated with a blur around the font, so the best result delivers wmf for Office 2010.
For Office 2013 and higher, I am using the following code to get emf right from the start and don't face issue about network drive/unc + label error.
var field = range.Fields.Add(range, WdEnums.WdFieldType.wdFieldLink);
field.LinkFormat.SourceFullName = fileName + $"!{label}";
Edit:
Here a screenshot of the main problem that I try to solve, as I reminder this is how it looks in Office 2010 in Office 2013 and higher both look decent:
For both I am using paste special
https://support.office.com/en-us/article/paste-special-e03db6c7-8295-4529-957d-16ac8a778719
The first table in the word document produces an EMF File, while using the paste special format "Picture (Enhanced Metafile)", macro recording produces this code:
Selection.PasteSpecial Link:=False, DataType:=wdPasteEnhancedMetafile, _
Placement:=wdInLine, DisplayAsIcon:=False
The second table in the word document produces an WMF File, while using the paste special format "Picture (Windows Metafile)", macro recording produces this code:
Selection.PasteSpecial Link:=True, DataType:=wdPasteMetafilePicture, _
Placement:=wdInLine, DisplayAsIcon:=False
On the right side, you can see the excel file I did copy to paste in the left word document.
As you can clearly see, Office 2010 renders/draws the WMF file (the second table in the word document) alot nicer, so that would be my desired output, but as I mentioned I have struggle replicating the PasteSpecial and keeping the WMF file that renders/draws better.
Edit2:
I recorded my screen to show the error, pls excuse that my environment is in german.
https://imgur.com/a/50wcBGQ
The code I have used is this:
Sub NetworkAndLabel()
'this will fail
Dim fileName As String
Dim label As String
'T is a mapped drive for the share \\NAS1\Ablage
fileName = "T:\rfa\TestFile.xlsx"
'label is in german, in english it would be Sheet1!R1C1:R1C2
label = "Tabelle1!Z1S1:Z2S2"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName & "!" & label, True
End Sub
Sub Network()
'this will run successfully
Dim fileName As String
Dim label As String
'T is a mapped drive for the share \\NAS1\Ablage
fileName = "T:\rfa\TestFile.xlsx"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName, True
End Sub
Sub LocalAndLabel()
'this will run successfully
Dim fileName As String
Dim label As String
'E is a local drive (second partition, not a seperate drive)
'up till now, I only tested with C and wanted to see if a simple second partition works or not
fileName = "E:\rfa\TestFile.xlsx"
'label is in german, in english it would be Sheet1!R1C1:R1C2
label = "Tabelle1!Z1S1:Z2S2"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName & "!" & label, True
End Sub
Sub Local_()
'this will run successfully
Dim fileName As String
Dim label As String
'E is a local drive (second partition, not a seperate drive)
'up till now, I only tested with C and wanted to see if a simple second partition works or not
fileName = "E:\rfa\TestFile.xlsx"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName, True
End Sub
I wrote "UsedRange" in C5 of the excel file, to show the differnt output in word if a label is or isn't in use, if I don't specify the label, it uses the UsedRange of the first sheet.
FYI, I have written the code in simple vba to demonstrate that it has nothing to do with C# and can nativly reproduced without anything special. In the end the solution, if there is one, will be included in my C# application.
Edit3:
Just to clarify, if someone knows a way to make Office 2010 render/draw the EMF file better, that would also be a valid solution, for my problem, because at the end of the day, I simply want to have a decent looking linked excel file in my word document. I don't really care if EMF or WMF, I am just trying to work with WMF because it looks better, and have the issues that I described, telling Office 2010 to stay on the WMF format.
Because the only way, I know of, to overcome the error message, is by manipulating the Field, as shown above, but once I call field.Update() the WMF file gets replaced with EMF, and I end up with the bad looking render/draw of the EMF file.
Edit4:
As requested, I had a look into the internal structure of the document and had a look at the differences. The actual difference is basically 0, only had stuff that should be irrelevent, like revisionnumber, characters count and stuff like this.
But I noticed the following, even though this code
Selection.PasteSpecial Link:=True, DataType:=wdPasteMetafilePicture, _
Placement:=wdInLine, DisplayAsIcon:=False
generates a WMF file, which I can see either by looking into the word\media folder and seeing there the produced image1.wmf, or by looking at the file word\_rels\document.xml.rels which has the following entry
<Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.wmf"/>
The actual XML for the OLE Object has the following in word\document.xml
<o:OLEObject Type="Link" ProgID="Excel.Sheet.12" ShapeID="_x0000_i1025" DrawAspect="Content" r:id="rId8" UpdateMode="Always"><o:LinkType>EnhancedMetaFile</o:LinkType><o:LockedField>false</o:LockedField></o:OLEObject>
As you can see the LinkType is defined as EnhancedMetaFile (EMF).
Since the OLE Object is defined like this, I tried if a simple call to field.Update would trigger the change from WMF to EMF, and sadly thats the case, so even without me modifing the field's code, a simple call like this
Selection.InlineShapes(1).Field.Update
will already trigger the conversion from WMF to EMF since the OLE Object is just simply defined like this, the conversion can also be achieved without any custom code, just select the inline shape and hit F9 or right click and select Update Links (translated from my german environment)
Notice that for what ever reason, this code
Selection.InlineShapes.AddOLEObject("Excel.Sheet.12", "E:\rfa\TestFile.xlsx", True).Field.Update
Will not trigger the conversion, but if you save the word document and open it again, than you can call field.Update to trigger the conversion.
So, to have the conversion in one go, without the necessity of saving/closing the word document, you need to atleast call this
With Selection.InlineShapes.AddOLEObject("Excel.Sheet.12", "E:\rfa\TestFile.xlsx!Tabelle1!Z1S1:Z2S2", True).Field
.Code.Text = Replace(.Code.Text, "Z1S1:Z2S2", "Z2S2:Z3S3")
.Update
End With

Generating GS1 DataMatrix using ZXing.Net

What I need
Is to generate a working GS1 DataMatrix, using this test content:
(240)1234567890(10)AA12345(11)123456(21)1(96)1234567
Steps
I've downloaded the nuget package from here:
and
I've created a console app that uses this code:
private static void DoGs1DataMatrixStuff()
{
var writer = new BarcodeWriter
{
Format = BarcodeFormat.DATA_MATRIX
};
writer
.Write("(240)1234567890(10)AA12345(11)123456(21)1(96)1234567")
.Save(#"C:\Temp\barcode.png");
}
There's no obvious specific GS1_DataMatrix format I can use ...
that gives me
which if read by a scanner app on my smartphone, gives the literal content that I originally presented, not with the FNC1 formatting that I expect for GS1:
(240)1234567890(10)AA12345(11)123456(21)1(96)1234567
while it should be
2401234567890 10AA12345 11123456211 961234567
From another source (not a source I can use) I got this barcode:
Using my smartphone app this reads into the correct data.
Question
How can I recreate this working GS1 datamatrix, using ZXing.Net?
also see
this link, Chris Bahns raises the same concern I have, but his request didn't get a working answer.
You have to use a formatted string with ASCII character 29 (GS - Group Separator):
< GS >2401234567890< GS >10AA12345< GS >11123456211< GS >961234567
(replace the "< GS >" with ASCII 29)
ZXing.Net supports the GS symbol with the ASCII encoder since version 0.15. It replaces the ASCII 29 value with the FNC1 codeword (232) in the resulting datamatrix image.
That's only a low level support. There is no built in class or something similar which understands AI (application identifiers) with fixed or variable length (similar to the result parser classes for vCards, vEvent, ISBN, ...).

How can I obtain the CRC from a CAN(Controller Area Network) message frame?

I have a project in which I need to create a perl script to parse a .hex file into a .can file full of CAN frames for to be sent. Once the file has been parsed it is going to be read by a C# based GUI that will translate those lines into proper CAN messages to be sent.
The list of aspects that I need to include for the .can is the following:
Add delays to TX commands
Add comments that the parser will ignore
Add a file header comment that the parser will ignore
When file was create, which file, parser version… etc.
Add a CRC (on the file itself)
Add an Application CRC (written to certain Flash memory location)
This is an example of the .hex file that I am parsing:
:020000040000FA
:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
Out of this list I am only missing number 4 and 5. I've been reading about what is CRC and how to make use of it, so I have some knowledge on the topic, but I do not know to implement points 4 and 5. I would appreciate some guidance on how to approach this issue. Below a sample of the .can file that I cam using:
//File used: app1FULL.hex
//Parser version: 0.2 alpha
//Date: Thu Oct 13 16:47:55 2016
TX:10:1537:8:45:EF:0B:F0:FF:FF:FF:FF //load flash
TX:10:1538:8:FA:CF:11:F0:FB:CF:12:F0 //load flash
TX:10:1539:8:E9:CF:13:F0:EA:CF:14:F0 //load flash
TX:10:1540:8:E1:CF:15:F0:E2:CF:16:F0 //load flash
TX:10:1541:8:D9:CF:17:F0:DA:CF:18:F0 //load flash
TX:10:1542:8:F3:CF:19:F0:F4:CF:1A:F0 //load flash
TX:10:1543:8:F6:CF:1B:F0:F7:CF:1C:F0 //load flash
TX:10:1544:8:F8:CF:1D:F0:F5:CF:1E:F0 //load flash
TX:10:1536:5:B:0:16:0:40:00:00:00:00:64 //flash write
RX:1000:1535:3:B:0:16:64 //expect response
PRINT:Boot has failed:Boot received all messages successfully
Thank you guys!

Why MigraDoc gives an "image not found" with this fileless image?

I have the "image.png" fileless image included in my WPF C# project as "embedded resourse". The full name of such image is "myapplication.image.png".
I am using such image in a document generated via MigraDoc. However, the document generated contains all the contenent that I planified, but a gray square within wrote "image not found" instead of image "image.png".
In order to use "image.png" in my document via MigraDoc, I added the file "image.png" as embedded resource to my project. Therefore, I followed this sample to include this image in the document.
My resulting code looks like the following:
byte[] imageStream = LoadImage("myapplication.image.png");
string imageFilename = MigraDocFilenameFromByteArray(imageStream);
Image image = para.AddImage(imageFilename);
Where "LoadImage" and "MigraDocFilenameFromByteArray" methods are coded as in the sample.
What am I missing?
Would someone provide a pointer, please?
If using NuGet, please note that you have to check 'Include prerelease' in order for MigraDoc v1.50.x to show up in the list of packages. Note that this is the 'Version', not the 'Runtime Version' number (right-click your MigraDoc reference and check properties). The most recent stable release is only v1.32.x.
As suggested by #User241.007, the issue was using 1.32 and nor 1.50 or later. Hence, everything is working now that I removed 1.32 and installed 1.50 via package manager.

Categories

Resources