MemoryStream to sbyte[] - c#

I'm still trying to add a jpeg image to a person in Open LDAP, using Novell's c# libraries:
Openldap: Add jpegPhoto to inetOrgPerson
There is a constructor for Novell.Directory.Ldap.LdapAttribute the with the following signature:
public LdapAttribute(string attrName, sbyte[] attrBytes)
So, I plan to use this one. But, how to convert a jpeg image from a MemoreyStream to sbyte[]?
MemoryStream.ToArray()
method returns byte[] and I don't know how to do it.

You can convert the array like this:
Array.ConvertAll(bytes, b => (sbyte)b)

On the CLR you can constant-time convert a byte[] to an sbyte[]. See my previous answer on this little-known trick.
(sbyte[])(object)MemoryStream.ToArray(); //compiles and runs

Related

type of variable in Visual C#

I am using DirectSound to record voice and save in binary code.
var problem = _dwCapBuffer.Read(offset, typeof(byte), LockFlag.None, _dwOutputBufferSize);
#"problem" is byte array arrcording to http://msdn.microsoft.com/en-us/library/windows/desktop/bb280844.aspx
but when I use "problem" in function like private string ByteArray_to_Hex(byte[] data)
ByteArray_to_Hex(problem), it show the error
the best overload method....has some valid argument
How can I solve this problem ( use the return value of CaptureBuffer.Read as byte[] ) ?
According to the documentation, it's not returning a byte array but an Array.
Just type ByteArray_to_Hex(problem) and let Visual Studio generate the method. Then you'll see what type it returns. Perhaps you can call ByteArray_to_Hex((byte[])problem) to explicitly cast it.

C# - Creating byte array of unknown size?

I'm trying to create a class to manage the opening of a certain file. I would one of the properties to be a byte array of the file, but I don't know how big the file is going to be. I tried declaring the byte array as :
public byte[] file;
...but it won't allow me to set it the ways I've tried. br is my BinaryReader:
file = br.ReadBytes(br.BaseStream.Length);
br.Read(file,0,br.BaseStream.Length);
Neither way works. I assume it's because I have not initialized my byte array, but I don't want to give it a size if I don't know the size. Any ideas?
edit: Alright, I think it's because the Binary Reader's BaseStream length is a long, but its readers take int32 counts. If I cast the 64s into 32s, is it possible I will lose bytes in larger files?
I had no problems reading a file stream:
byte[] file;
var br = new BinaryReader(new FileStream("c:\\Intel\\index.html", FileMode.Open));
file = br.ReadBytes((int)br.BaseStream.Length);
Your code doesn't compile because the Length property of BaseStream is of type long but you are trying to use it as an int. Implicit casting which might lead to data loss is not allowed so you have to cast it to int explicitly.
Update
Just bear in mind that the code above aims to highlight your original problem and should not be used as it is. Ideally, you would use a buffer to read the stream in chunks. Have a look at this question and the solution suggested by Jon Skeet
You can't create unknown sized array.
byte []file=new byte[br.BaseStream.Length];
PS: You should have to repeatedly read chunks of bytes for larger files.
BinaryReader.ReadBytes returns a byte[]. There is no need to initialize a byte array because that method already does so internally and returns the complete array to you.
If you're looking to read all the bytes from a file, there's a handy method in the File class:
http://msdn.microsoft.com/en-us/library/system.io.file.readallbytes.aspx

Write Int array to Stream in .NET

what's the best way to write the binary representation of an int array (Int32[]) to a Stream?
Stream.Write only accepts byte[] as source and I would like to avoid converting/copying the array to an byte[] (array but instead streaming directly from the 'original location').
In a more system-oriented language (a.k.a. C++) I would simply cast the int array to a byte* but as far as I understood this isn't possible with C# (and moreover, casting byte* to byte[] wouldn't work out either way)
Thanks
Martin
PS: Actually, I would also like to stream single int values. Does using BinaryConverter.GetBytes() create a new byte array? In this case I extend my question to how to efficiently stream single int values ...
The simplest option would be to use BinaryWriter wrapping your output stream, and call Write(int) for each of your int values. If that doesn't use the right endianness for you, you could use EndianBinaryWriter from my MiscUtil library.
I don't know of anything built-in to do this more efficiently... I'd hope that the buffering within the stream would take care of it for the most part.
System.Array and System.Int32 both have the SerializableAttribute and so both support default serialization in a retrievable format.
http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx
There is sample code for Binary output and readback here:
http://msdn.microsoft.com/en-us/library/aa904194(VS.71).aspx

passing the right BytesArray into the MemoryStream for Image

there a way to determine that I am passing the right byte array to the MemoryStream if I want to create an Image out of byte array.
MemoryStream mStream = new MemoryStream();
mStream.Write(byteArray, 0, byteArray.Lenth);
Image imgObj = Image.FromStream(mStream);
How can I, if possible Correct the byteArray that it is a valid byteArray for an Image?
This is a really ominous question, surely you must know where you are reading your data from? When you create an image using Image.FromStream, an ArgumentException will be thrown if it cannot recognise the format. Why don't you use that mechanism for identifying an incorrect stream of data, rather than re-invent the wheel?
I've done a bit of programatic image manipulation myself. The thing you'll want to do is find the spec for the image format that you are modifying and make sure you do everythign you should. For example png files are chunked and have checksums on each section so if you change something in that chunk you have to recalculate the checksum at the end of the section.
After reading your questions and your comments, i think what you're trying is to manipulate the image by manipulating the byte array before you put it into the Image class. And now you claim that your byte array is corrupt for this image format and how you can correct it.
So the answer to this question would be: You corrupted it, you'll fix it.
But to really solve your problem, if your goal is to manipulate the picture itself, just load it into an interims Image and use the Graphics class to manipulate your picture. Afterwards put the result into the real image object you like. Ready, without any hassle about working on the byte array.
here's the answer Image Processing for Dummies with C# and GDI+
OT: i don't know how to put links on comments so I put it in the answers.

How can I take a byte array of a TIFF image and turn it into a System.Drawing.Image object?

I have a byte[] array, the contents of which represent a TIFF file (as in, if I write out these bytes directly to a file using the BinaryWriter object, it forms a perfectly valid TIFF file) and I'm trying to turn it into a System.Drawing.Image object so that I can use it for later manipulation (feeding into a multipage TIFF object)
The problem I'm having is that the commonly accepted code for this task:
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms, true);
return returnImage;
}
doesn't work for me. The second line of the above method where it calls the Image.FromStream method dies at runtime, saying
Parameter Not Valid
I believe that the method is choking on the fact that this is a TIFF file but I cannot figure out how to make the FromStream method accept this fact.
How do I turn a byte array of a TIFF image into an Image object?
Also, like I said the end goal of this is to have a byte array representing a multipage TIFF file, which contains the TIFF files for which I have byte array objects of right now. If there's a much better way to go about doing this, I'm all for it.
OK, I found the issue, and it was from a part of the code unrelated to the part of the code I was asking about. The data was being passed as a string, I was converting it to a byte array (this was a test rig so I was trying to simulate the byte array that I get in the main app), then converting that to a MemoryStream, then making an Image from that.
What I failed to realize was that the string was Base64 encoded. Calling Convert.FromBase64String() caused it to turn into a byte array which wouldn't kill the Image.FromStream() method.
So basically it boiled down to a stupid mistake on my part. But hey, the code above is still useful and this page will probably serve as a Google result as to how to avoid this mistake to someone else.
Also, I found an easy way to construct a Multi-Page TIFF from my byte arrays here.
Edit: The assumption below is not correct, I had a chance to fire up my IDE later and tested with and without Write and both populated the MemoryStream correctly.
I think you need to write to your MemeoryStream first.
As if my memory (no pun intended) serves me correctly this:
MemoryStream ms = new MemoryStream(byteArrayIn);
Creates a memory stream of that size.
You then need to write your byte array contents to the memory stream:
ms.Write(byteArrayIn, 0, byteArrayIn.Length);
See if that fixes it.
All these were clues that helped me figure out my problem which was the same problem as the question asks. So i want to post my solution which i arrived at because of these helpful clues. Thanks for all the clues posted so far!
As Time Saunders posted in his answer, that Write method to actually write the bytes to the memory stream is essential. That was my first mistake.
Then my data was bad TIFF data too, but in my case, i had an extra character 13 at the beginning of my image data. Once i removed that, it all worked fine for me.
When i read about some basic TIFF file format specs, i found that TIFF files must begin with II or MM (two bytes with values of either 73 or 77). II means little-endian byte order ('Intel byte ordering') is used. MM means big-ending ('Motorola byte ordering') is used. The next two bytes are a two byte integer value ( = Int16 in .NET) of 42, binary 101010.
Thus a correct TIFF stream of bytes begins with the decimal byte values of: 73, 73, 42, 0 or 77, 77, 0, 42. I encourage anyone with the same problem that we experienced to inspect your TIFF data byte stream and make sure your data is valid TIFF data!
Thanks Schnapple and Tim Saunders!!

Categories