How to save compressed pixels (compressed with my own encoder) back into DICOM image file using Imebra library? - c++

I have my own image encoder and decoder. What I want is to read DICOM images, extract uncompressed image pixels, compress them using my encoder and then write those compressed pixels back in the DICOM file in place of uncompressed pixels. Decoder would do the opposite. Is this possible to do in Imebra? I can read tags and pixels, but after I compress them, I'm not sure how to put them back (they are currently in char* buffer), or if this is even possible. I'm using Imebra in C++.
Alternatively, it would be okay if I could create completely new DICOM file, but in that case I would need to easily transfer all the DICOM tags from the old file.
If this is not possible in Imebra, is there some other C++ library that allows this?
Edit:
Thanks for the answer, Paolo. However, original DICOM image still remains unchanged (using second option). Can you say am I doing something obviously wrong here?
std::unique_ptr<imebra::DataSet> loadedDataSet(imebra::CodecFactory::load(imgNameM));
imebra::WritingDataHandlerNumeric* dataHandler = loadedDataSet->getWritingDataHandlerRaw(imebra::TagId(imebra::tagId_t::PixelData_7FE0_0010), 0);
dataHandler->assign(buffer, size);
delete dataHandler;
loadedDataSet is not empty, I checked with bufferExists.
Edit 2:
Yes, I didn't save it. Now I added that line and managed to modify PixelData element which was solves my original problem. Thanks. However, some other parts of the file are now automatically also changed. More than 100 empty bytes are added at the beginning of the file, although this doesn't bother me that much. What bothers me is that (0008,0005) Specific Character Set tag is now added and its value isn't set (it's empty) which then causes CharsetConversionNoTableError when trying to read tags of that modified file. If I remove that tag manually and fix the group length, I can read tags normally. Is there a possibility to avoid this behavior?

Imebra already provides the encoder/decoder for lossless jpeg, baseline and extended jpeg, RLE.
There are several ways of adding your own codec to Imebra:
derive a class from imebra::implementation::codecs::imageCodec
or encode an image into a char buffer, then add it as raw content using imebra::DataSet::getWritingDataHandlerRaw which allows you to write the tag raw content. getWritingDataHandlerRaw returns a WritingDataHandlerNumeric. Use WritingDataHandlerNumeric::assign to move the bytes buffer into the data handler, then delete the data handler to cause it to commit its content into the dataset.
The example changeTransferSyntax that comes with the library shows how to create a new dataset with all the same tags from the source dataset but with a different transfer syntax (including a different image compression)

Related

Taglib read ID3v2 tags from arbitrary file c++

I'm trying to use the TagLib C++ API to read ID3v2 metadata from an arbitrary audio file. This file is not necessarily an .mp3 file, and may be of the other common audio formats. I have the following:
std::string readId3v2Tag(std::string filePath, std::string tagName) {
// read from file
TagLib::FileRef f(filePath.c_str());
if (!f.isNull() && f.file()) {
// get tags from property map
TagLib::PropertyMap tags = f.file()->properties();
if (tags.find(tag) != tags.end()) {
return std::string(tags[tag][0].toCString());
}
}
}
However, when I input an ID3v2 frame name, it doesn't return anything. I believe this is because the f.file()->properties() map contains TagLib's tag format. I must be able to access ID3v2 frames by name.
I have been told to use the ID3v2 class, however I don't see how to access this from a file, and am having trouble reading the API docs. Does anyone know how to do this?
Always read the manual: it tells you to not use the file() approach. Also properties() won't give you ID3v2 tag frames - you should iterate all of them to see their keys and values.
Instead
use MPEG::File (see manual) and from there go/read on
over ID3v2Tag() (see manual)
to frameList() (see manual).
It's pretty straightforward once the terms are clear: a file can have zero to multiple tags, where a ID3v2 tag can have one to multiple frames. The file alone however can also have multiple properties that are unbound to tags (i.e. audio duration, bit depth...) - no wonder that none of your frame names you search for won't show up in the file's properties.

Adobe Photoshop 'Save As' Action

I'm trying to save a large number of images in JPEG format. Each file combines 2 layers visible on the screen. To achieve this, I've recorded a simple action that saves the file as X.jpg. I don't mind the fact that it saves the next file as X copy.jpg, but the problem occurs when trying to save the 3rd image (and other consecutive images), as instead of creating another file, it replaces the previous X copy.jpg file with the 3rd image.
Does anyone know how to instruct it to keep creating new files instead of rewriting the X copy one?

When using SimpleCV with GeoTiffs what is the best way to keep the georeferencing data?

I have searched the internet at depth looking for help on this. I have two images (before and after) that are georeferened and georectifyed to be right on top of one another. I am using Simple CV hopefully for some indepth analysis and changed between the image. Right now I am just getting familiar with Simple CV and am using the blob detection. Here is my code:
from SimpleCV.base import *
from SimpleCV.Features import *
from SimpleCV.ImageClass import *
from SimpleCV.Display import *
var1 = Image("C:\Users\pathname\image.tif")
var1.show()
blobs = var1.findBlobs()
blobs[-1].draw() #The blobs[-1] fills in the blob
var1.show()
var1.save("C:\pathname\Blobfill1.tif")
I do the the blob detection on the before and after image and save them both as tifs. However when I begin to subtract to the images or even bring both images back into ArcMap, they have have lost all their spatial reference data and no long right on top of one another. It is very important that the two images stay exactly right on top of one another during my analysis period. Appreciate any help!
It appears to me that SimpleCV is simply not saving the exif data in the image file. I doubt it is reading it at all when you are loading the file.
The easiest way may be to open the file as you have use something like pyexiv2 (http://tilloy.net/dev/pyexiv2/) to read the exif information including the georeferencing.
When finished save as you have and use pyexiu2 to save the georeferencing back to the saved file.

How to keep the original image format when inserted into a CRichEditCtrl?

I used the COleRichEditCtrl class in this page http://www.codeproject.com/KB/edit/COleRichEditCtrl.aspx
So I can insert an image into the CRichEditCtrl using copy & paste.
However, it appears that it will automatically convert the image into an uncompressed WMF format when i paste the image. As a result, when I copy a JPG of size 500KB and paste it into the control, then use StreamOut() to store the content into a .rtf file, the file size will be as large as 6MB!! This is certainly unacceptable. So is there a way to keep the original format of the image so the size doesn't boost? Many many thanks!
Whatever you copy and paste in the RichEdit control, while saving that file, it always convert the content into RTF format. If you only link the image file, the size of your document will be very small. But if you embed it in your document, the size will increase. There is no other option.

Plot a graph in the html file using Django

I am doing a monitoring system using Django. In my views file, I have defined one class called showImage which collects the information necessary to plot a graph using matplotlib.
At the beginning, I just stored the image in a string buffer to represent it with HttpResponse:
buffer = StringIO.StringIO()
canvas = pylab.get_current_fig_manager().canvas
canvas.draw()
pilImage = PIL.Image.fromstring("RGB", canvas.get_width_height(), canvas.tostring_rgb())
pilImage.save(buffer, "PNG")
# Send buffer in a http response the the browser with the mime type image/png set
return HttpResponse(buffer.getvalue(), mimetype="image/png")
However, I need to implement some javaScript in the html file to add more applications. For that reason, I have decided to save the image in a variable and plot it in the html file:
# serialize to HTTP response
response = HttpResponse(buffer.getvalue(), mimetype="image/png")
return render_to_response('eQL/dev/showImage.html', {'response':response})
My question is that I don't really know how to represent it in the html file because I didn't find any example doing it. Any one knows the answer?
Thanks in advance!
Do you mean that in your first implementation, your response was a PNG file, but now you wish to make the response an HTML file instead, containing the image?
Well firstly, you need to change the response MIME type from image/png to text/html or similar.
Secondly, I'm not sure why you are passing a HttpResponse object (containing the PNG data) into the template. Can the template even read that? Surely you just want to be passing the raw PNG data, not a HttpResponse object.
Finally, how to do it. Well as you may know, HTML isn't so great at embedding images. As with normal websites, you can include text in the page, but if you want an image, you need a separate file and link to it using the <img src="..." /> element. This is tricky to do dynamically: it means you need to setup two separate URLs (one for the PNG and one for the HTML), which run independently of one another (you can't just have one piece of code; you need one handler for generating the PNG and the other for generating the HTML), and have the HTML link to the PNG URL.
If that is too hard, there is another way out, but it is a bit hacky: data URLs. They let you include image data in the HTML page itself, so you only need to produce one response. Unfortunately it is not well supported in Internet Explorer pre-9. IE8 supports images less than 32K, IE7 and below don't work. See the example on Wikipedia -- you are aiming to generate something like this:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />
Basically, take the PNG data, and Base64-encode it (use Python's base64 library). Then just put "data:image/png;base64," in front of it, and set that as the URL for the img src. In other words, pass the Base64-encoded string to Django's template engine, and construct the URL as part of the img tag in the template.