I have a 2D short array coming from a C++ library. The array contains the pixels of a 16 bit grayscale image. I am trying to convert it to Base64 to display it. My C# code is as follows:
string picture_path = "~/Picture/CT_Axial_Z/CT_Axial-Z_0111.png";
string path = System.Web.Hosting.HostingEnvironment.MapPath(picture_path);
if (File.Exists(path))
{
IntPtr gpget = Open16BitGrayImage(path);
CImage_DLL gget = (CImage_DLL)Marshal.PtrToStructure(gpget, typeof(CImage_DLL));
int short_size = sizeof(short);
int p_s_cursor = 0;
Array pshImageData = Array.CreateInstance(typeof(short), gget.m_nH, gget.m_nW);
for (int i = 0; i < gget.m_nH; i++)
{
for (int j = 0; j < gget.m_nW; j++)
{
short data = (short)Marshal.PtrToStructure(gget.pshImageData + p_s_cursor, typeof(short));
pshImageData.SetValue(data, i, j);
p_s_cursor += short_size;
}
}
}
I need to convert it to Base64 and display it on a canvas. How should I do it?
Related
For example i've got one array like
int[] array = {1,0,0,1,0}
and one int variable=0;
I want set all array's elements into variable. How can i do this?
variable=10010
In addition if we think about reverse of this situation? Variable's values set to array?
int something=10000 to int[] something={1,0,0,0,0}
Thanks for your all contribution
//==============go forwards===================
int[] array = { 1, 0, 0, 1, 0 };
int variable = 0;
for (int i = 0; i < array.Length; ++i)
{
//first element
if (i == 0)
variable = array[i];
else
{
variable *= 10;
variable += array[i];
}
}
//print resualts
Console.WriteLine(variable);
//===================go backwards===============
int variable2 = 10010;
//convert it into a char array
string value = variable2+"";
//set the array length based on the size
int[] reverse = new int[value.Length];
//loop
for (int i = 0; i < value.Length; ++i)
{
//grab the number from a char value and push it into the array
reverse[i] = (int)Char.GetNumericValue(value[i]);
}
//print out
for(int i = 0; i <reverse.Length;++i)
{
Console.WriteLine("[" + i + "] = " + reverse[i]);
}
Yet another way to do this, but not as compact as others. This approach demonstrates bit-wise operations to construct an int from the array of 0's and 1's.
class Program
{
// converts array of 0's and 1's to an int, and assumes big endian format.
static int bitArrayToInt(int[] bit_array)
{
int rc = 0;
for (int i = 0; i < bit_array.Length; i++)
{
rc <<= 1; // bit shift left
rc |= bit_array[i]; // set LSB according to arr[i].
}
return rc;
}
static void Main(string[] args)
{
int[] array = { 1, 0, 0, 1, 0 };
int rc = bitArrayToInt(array);
System.Console.WriteLine("{0} = {1} binary",rc, Convert.ToString(rc, 2));
System.Console.ReadLine();
}
}
There's a huge number of choices on how to approach the problem.
Shortest quickest method I could think of.
byte[] array = { 1, 0, 1, 0, 0 };
string temp = "";
int result = 0;
for (int i = 0; i < array.Length; i++)
temp += array[i].ToString();
result = Convert.ToInt32(temp);
I'm on my phone here, so bear with me, but if performance isn't an issue then how about something like:
int.Parse(string.Join(string.Empty, array.Select(d => d.ToString()));
Obviously you'll need some error handling around the parsing for overflows, invalid characters, etc.
XFunction is a CLI to managed C++ code (wrapper).
I want to use XFunction(int,sbyte**) in my C# Project and convert String array to sbyte**.
sbyte[][] sbytes = new sbyte[7][];
for (int argCounter = 0; argCounter < 7 ; argCounter++)
{
//get the byte array
byte[] bytes = Encoding.ASCII.GetBytes(argument[argCounter]);
//convert it to sbyte array
sbytes[argCounter] = new sbyte[bytes.Length];
for (int i = 0; i < bytes.Length; i++)
sbytes[argCounter][i] = (sbyte)bytes[i];
}
when I calling:
XFunction(7,sbytes);
and buid, generate this error:
The best overloaded method match for 'XFunction(int, sbyte**)' has
some invalid arguments Argument 2: cannot convert from 'sbyte[][]'
to 'sbyte**'
How can I fixed this error???
You need to use fixed to get pointer to your array and to prevent garbage collection from relocating your variable.
You may want to do something like this:
public static unsafe void CallXFunction(int a, sbyte[][] array)
{
var pointerArray = new sbyte*[array.Length];
// Recursive fixing so that whole array get's pinned at same time
// (never use fixed pointer outside of fixed{} statement)
Action<int> fixArray = null;
fixArray = (pos) =>
{
fixed (sbyte* ptr = array[pos])
{
pointerArray[pos] = ptr;
if (pos <= (array.Length - 2))
{
fixArray(pos + 1);
}
else
{
fixed (sbyte** pointer = pointerArray)
{
XFunction(a, pointer);
}
}
}
};
fixArray(0);
}
it solved by:
sbyte[][] sbytes = new sbyte[6][];
for (int argCounter = 0; argCounter < 6 ; argCounter++)
{
get the byte array
byte[] bytes = Encoding.ASCII.GetBytes(argument[argCounter]);
convert it to sbyte array1
sbytes[argCounter] = new sbyte[bytes.Length];
for (int i = 0; i < bytes.Length; i++)
sbytes[argCounter][i] = (sbyte)bytes[i];
}
unsafe
{
fixed (sbyte* junk = &sbytes[0][0])
{
sbyte*[] arrayofptr = new sbyte*[sbytes.Length];
for (int i = 0; i < sbytes.Length; i++)
{
fixed (sbyte* ptr = &sbytes[i][0])
{
arrayofptr[i] = ptr;
}
}
fixed (sbyte** ptrptr = &arrayofptr[0])
{
XFunction(7, ptrptr);
}
}
}
I find myself converting 1D byte and single arrays to 2D by doing the following. I suspect it is probably as fast as other methods, but perhaps there is a cleaner simpler paradigm? (Linq?)
private static byte[,] byte2D(byte[] input, int height, int width)
{
byte[,] output = new byte[height, width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
output[i, j] = input[i * width + j];
}
}
return output;
}
private static Single[,] single2D(byte[] input, int height, int width)
{
Single[,] output = new Single[height, width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
output[i, j] = (Single)input[i * width + j];
}
}
return output;
}
This doesn't help with making the code inside the methods cleaner, but I noticed that you have 2 basically identical methods that differ only in their types. I suggest using generics.
This would let you define your method only once. Using the where keyword, you can even limit the kind of types you allow your method to work on.
private static T[,] Make2DArray<T>(T[] input, int height, int width)
{
T[,] output = new T[height, width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
output[i, j] = input[i * width + j];
}
}
return output;
}
You would call this method like this
int[] a; //or any other array.
var twoDArray = Make2DArray(a, height, width);
Buffer.BlockCopy(input, 0, output, 0, input.Length); is faster, but fastest is to not copy the array at all.
If you don't really need a separate 2D array, you can just access your 1D array like a 2D array trough a function, property, or custom type. For example:
class D2<T> {
T[] input;
int lenght0;
public d2(T[] input, int lenght0) {
this.input = input;
this.lenght0 = lenght0;
}
public T this[int index0, int index1] {
get { return input[index0 * this.lenght0 + index1]; }
set { input[index0 * this.lenght0 + index1] = value; }
}
}
...
byte[] input = { 1, 2, 3, 4 };
var output = new D2<byte>(input, 2);
output[1, 1] = 0; // now input is { 1, 2, 3, 0 };
Also, in .NET access to multidimensional arrays is a bit slower than access to jagged arrays
Generic function:
private static b[,] to2D<a, b>(a source, valueAt: Func<a, int, b>, int height, int width)
{
var result = new b[height, width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
result[i, j] = valueAt(source, i * width + j);
}
}
return result;
}
var bytes = to2D<byte[], byte>([], (bytes, at) => bytes[at], 10, 20);
I know I am late to the party, but if you want to access a 1d array, list, etc. like it were an n-dimensional array (without copying) you can use https://github.com/henon/SliceAndDice to do so without copying.
// create a 2D array of bytes from a byte[]
var a = new ArraySlice<byte>( new byte[100], new Shape(10,10));
// now access with 2d coordinates
a[7,9]=(byte)56;
Of course, everyone can do it for simple 2d, 3d, ... nd volumes easily. But this lib also allows to do slicing of n-dimensional arrays without copying.
I have been assigned to convert a C++ app to C#.
I want to convert the following code in C# where rate_buff is a double[3,9876] two dimensional array.
if ((fread((char*) rate_buff,
(size_t) record_size,
(size_t) record_count,
stream)) == (size_t) record_count)
If I correctly guessed your requirements, this is what you want:
int record_size = 9876;
int record_count = 3;
double[,] rate_buff = new double[record_count, record_size];
// open the file
using (Stream stream = File.OpenRead("some file path"))
{
// create byte buffer for stream reading that is record_size * sizeof(double) in bytes
byte[] buffer = new byte[record_size * sizeof(double)];
for (int i = 0; i < record_count; i++)
{
// read one record
if (stream.Read(buffer, 0, buffer.Length) != buffer.Length)
throw new InvalidDataException();
// copy the doubles out of the byte buffer into the two dimensional array
// note this assumes machine-endian byte order
for (int j = 0; j < record_size; j++)
rate_buff[i, j] = BitConverter.ToDouble(buffer, j * sizeof(double));
}
}
Or more concisely with a BinaryReader:
int record_size = 9876;
int record_count = 3;
double[,] rate_buff = new double[record_count, record_size];
// open the file
using (BinaryReader reader = new BinaryReader(File.OpenRead("some file path")))
{
for (int i = 0; i < record_count; i++)
{
// read the doubles out of the byte buffer into the two dimensional array
// note this assumes machine-endian byte order
for (int j = 0; j < record_size; j++)
rate_buff[i, j] = reader.ReadDouble();
}
}
I have image in C# and I created array of that but
for filtering and mask the picture I need 2 dimensional Array of image
thank for your help!
Creating a 2d array from your image, or from your 1d array, is pretty straightforward. Here is the way to do it from your 1d array, although this can be easily translated directly to your image code:
int[][] To2dArray(int[] source, int width)
{
int height = source.Length / width;
int[][] result = new int[height][width];
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
result[i][j] = source[i * width + j];
}
}
return result;
}