i have a 1D array. I copied the data onto a 8 bit color bitmap object. And i saved it. I opened the bitmap in hex editor and found the original array data but to my surprise i saw a lot of information before the array data. I think this section belongs to the header right ?
I have attached a screenshot of the hex view
OK, let's take a look at the Bitmap format:
http://en.wikipedia.org/wiki/BMP_file_format#Bitmap_file_header
If you follow this, the first thing you will learn is that your data is 0x436 (1078) bytes away... right around where you are saying it is.
The file header is 14 bytes long. In this case, the information header is the next 40 bytes long. 1078 - 14 - 40 = 1024. That means there is 1K between the headers and the data itself. The spec states that the next section is the color table. At 4 bytes per color, this table contains 256 colors.
After that, you get your image.
So, most of that bloat that you are seeing is the default 256 color table that .Net is putting in there.
In the header, it is using 1 byte per pixel, which means that the lookup table needs to be 2^8 bytes long, which is 256 colors, which is 1024 bytes.
Not all header formats require the color table to be completely filled, but it can be easily extrapolated why the bitmap producer (.Net) would decide to fill the color table in completely... at least for the first 256 colors.
Yes.
Here is a description of the bitmap file format: http://en.wikipedia.org/wiki/BMP_file_format
Related
In C# I want to replace example bytes number 200-5000 by an array/stream of 30000 bytes inside a file, the numbers are just for example, the sizes may vary, I could be replacing a section with either more or less bytes than the size of the section.
I have checked this question:
Replace sequence of bytes in binary file
It only explains how to override a fixed-sized section and will overwrite data after if the byte array length is bigger than original section and will leave old bytes in place if the section to be replaced is bigger than the new bytes.
Higher performance and not having to read the entire file into memory would be preferred, but anything goes.
I would need this to work both on windows and linux.
When I try to understand SFML, I tried to set an icon with RenderWindowInstanse.SetIcon()
the method, that takes 3 parameters, fist two is size, 3 - byte[], then I try to use File.ReadAllBytes()
and same tools in c#, but that don't work, I search and find on-site ImageInstanse.Pixels property that returns byte[] like a parameter, that's works but I don't understand why they are returning different byte arrays
In SFML.NET, Image.Pixels returns an array of bytes that are nicely organized RGBA pixel values that represent the image in memory.
.NET's own File.ReadAllBytes() function returns the bytes that come from the file itself in the system's storage device.
Every file has a format that defines the layout and meaning of the bytes that make up that file. Image files are an extension of that concept as there any many different file formats for images. The pixel data for an image has to be encoded (and/or compressed) according to the format it is being saved as. This means that the bytes in the file no longer matches the raw RGBA pixel data as it was in the computer memory.
Files often contain lots of extra bytes for things like a file header, metadata, compression information, or possibly even an index for blocks of data that are smaller files or images within a file.
When you use File.ReadAllBytes(), you are given all of the bytes that represent this data in an array and you have to know exactly what the meaning of the byte at each index is.
SFML understands how to decode many different image formats, and will read the bytes of the file and process that into an array of pixel data. This is what the constructor for Image that takes a file is doing in the background. Once you have an SFML.Graphics.Image instance, you can use its Pixels property to access that decoded RGBA pixel data.
I want to display DICOM file having photometric interpretation MONOCHROME2.
some of the specifications of image are-
Rows: 1024
Columns: 1024
No of Frames: 622
Bits Allocated: 16
Bits Stored: 10
High Bit: 9
Pixel Representation: 0
Sample per pixel: 1
I am using gdcmRegionReader to extract single frames byte array in the following way.
gdcm.ImageRegionReader _regionReader = new gdcm.ImageRegionReader();
_regionReader.SetRegion(_boxRegion); // _boxRegion is some region
_regionReader.ReadIntoBuffer(Result, (uint)Result.Length);
Marshal.Copy(Result.ToArray(), 0, _imageData.GetScalarPointer(),
Result.ToArray().Length);
_viewer.SetInput(_imageData); // _viewer = vtkImageViewer
But when i display that file it is displaying like this..
but the original image is like this..
So can someone help me on how to load and display MONOCHROME2 dicom images.
Disclaimer: I never used the toolkit in question. I am attempting to answer based on my understanding of DICOM. In my experience about DICOM, syntax was rarely was the problem. Real problem was the concept and terms.
I see two problems in output.
One is about part of the image rendered. Notice that entire data is not rendered in your output. Check the toolkit document to see how to set the dimensions/bounds while rendering image.
Other problem is about output quality. Initially, I suspected the Transfer Syntax might be the issue. I do not think it is but just make sure you are uncompromising the image before rendering. I am not sure how your toolkit handles compression while rendering.
There is other way available to render pixel data in the toolkit.
_ImageViewer.SetRenderWindow(renderWindow);
_ImageViewer.GetRenderer().AddActor2D(sliceStatusActor);
_ImageViewer.GetRenderer().AddActor2D(usageTextActor);
_ImageViewer.SetSlice(_MinSlice);
_ImageViewer.Render();
Above code is copied from "http://www.vtk.org/Wiki/VTK/Examples/CSharp/IO/ReadDICOMSeries". Detailed code is available there.
Following links may also be helpful:
http://vtk.1045678.n5.nabble.com/How-to-map-negative-grayscale-to-color-td5737080.html
https://www.codeproject.com/Articles/31581/Displaying-bit-Images-Using-C
You should really use vtkGDCMImageReader2 instead in your code. vtkGDCMImageReader2 precisely encapsulate gdcm::RegionReader for binding with VTK.
If for some reason you cannot use directly this class, simply copy/paste the C++ code from within the main function, into your C# code.
See:
http://gdcm.sourceforge.net/2.6/html/classvtkGDCMImageReader2.xhtml
http://gdcm.sourceforge.net/2.6/html/classgdcm_1_1ImageRegionReader.xhtml
I'm working on a file reader for a custom file format. Part of the format is like the following:
[HEADER]
...
[EMBEDDED_RESOURCE_1]
[EMBEDDED_RESOURCE_2]
[EMBEDDED_RESOURCE_3]
...
Now what I'm trying to do is to open a new stream that its boundaries are only one resource, for instance EMBEDDED_RESOURCE_1's first byte is at the 100th byte and its length is 200 bytes so its boundaries are 100 - 300. Is there any way to do so without using any buffers?
Thanks!
Alternatively - MemoryStream.
Before reading the necessary number of bytes set the initial position of the position by the property - Position.
But it is necessary to read the entire file into MemoryStream.
Is it possible to read the ID3 tags of an MP3 stored online without actually downloading the entire file?
I've used TagLib Sharp, but to my knowledge you actually have to open the file to read the ID3 tags.
As Florian said above, you can use an HTTP Range to read a little bit of the file and see whether there is an ID3 or not, then read the rest of the tag (if present/necessary). For example:
Range: bytes=0-65535
An ID3 tag may include an image, so it could be really large (I've seen some that are 500Kb). However, most of the useful information, such as the title, description, etc. is likely going to be available in the first few Kb. Depending on your connections (or expected client's connections), I would select a first number of Kb to download. For most connections, 64Kb is going to be really fast now a day (maybe it was less so in 2014).
Note that the entire file could also be less than 64Kb total. The Range request should still work, only it will return the file size. In that case, you'll never send a second request for more data.
An MP3 file with an ID3 tag starts like so:
0x49 0x44 0x33 ID3
0x03 0x00 major.revision (2.0 or 3.0)
0x00 flags
0xSS 0xSS 0xSS 0xSS size
Notes about the version:
The tag is ID3, that 3 is not part of the version
The first version is 2 because MP3 already had a TAG capability and that was considered to be version 1 (and 1.1 in certain conditions).
At this time, I've not see any revision other than 0. This is why we reference tags as ID3v1 (TAG), ID3v2 (ID3 + 0x02), and ID3v3 (ID3 + 0x03).
The 0xSS represents the size. This is an interesting one because only 7 bits are used in each byte to avoid 0xFF which is the synchronization code for MP3 (MPEG) files. Only they forget to do something about 0xFF found in PNG and JPEG images... Anyway...
The way to calculate the size is like this:
size = (buffer[pos + 6] << 21) +
(buffer[pos + 7] << 14) +
(buffer[pos + 8] << 7) +
(buffer[pos + 9] << 0)
IMPORTANT: You should verify that bit 7 is not set in any of those bytes. If set, then it's not a valid ID3 tag. This is why I don't do a (buffer[pos + n] & 0x7F), the & 0x7F part is not required if you properly verified the size early.
Note that this size does not include the size of the header. So keep in mind there are 10 bytes for the header.
The rest of buffer is organized in frames. These are either 3 letters, a size and the data of that frame, or 4 letters, a size, flags, and data. The header of each frame is determined by the version (2 or 3).
Anyway, once you have that size, if you want to read the entire ID3, you can do another GET to the HTTP server and retrieve the remaining data if the first 64Kb (or whatever size you used first) is not already larger or equal to the necessary size.
Range: bytes=65536-<size + 10 - 1>
The size is the data within the ID3. The +10 is for the header. The -1 is because the HTTP range is inclusive (not a size, it's a position).
IMPORTANT NOTE: All servers do not accept the Range header. If you are in control and your server doesn't support range requests, you may want to consider adding a proxy in front of the server. nginx is really good at that. It can cache the entire file and return just the range(s) requested in the HTTP header.