working with images as byte[] arrays

  • Thread starter Stephen.Schoenberger
  • Start date
S

Stephen.Schoenberger

I am working with some images as byte[] arrays and am not sure nor can
I figure out if as I am reading the image and saving smaller sub-
images I am reading across and down the image or down and back up or
randomly? I need to know so in turn I can realize what the coordinates
are of the sub-images. Here is a snippet of the code that is
performing this task...

for (int a = 1; a < 4800; a++) //will create 4800 sub images if a
goes to numsubimages
{
Bitmap tempbitmap;
//this declares the size of tbyte to be 768 which is
the number of bytes needed for 16x16 sub image
byte[] tbyte = new byte[(stride * height) / ((height /
16) * (width / 16))];
byte[] holding2 = new byte[tbyte.Length];

for (int b = 1; b < tbyte.Length; b++)
{
tbyte.Initialize();
byte holding = (byte) bytebitmap.GetValue(b*a);
tbyte.SetValue(holding, b);

}
tempbitmap = BytesToBmp(tbyte, tempSize); //save the
output of the 16x16 sub image so results can be seen
}

BytesToBmp is simply a function that coverts a byte array into a
bitmap image.

Thanks!
 
J

Jon Skeet [C# MVP]

I am working with some images as byte[] arrays and am not sure nor can
I figure out if as I am reading the image and saving smaller sub-
images I am reading across and down the image or down and back up or
randomly? I need to know so in turn I can realize what the coordinates
are of the sub-images. Here is a snippet of the code that is
performing this task...

My first reaction is that *twice* you've got an off by one error:
for (int a = 1; a < 4800; a++) //will create 4800 sub images

No, it won't. It will create 4799 - 1, 2, 3, 4... 4799.

In C# you almost always count from 0:

for (int a=0; a < 4800; a++)
....

You've got the same error later:

for (int b = 1; b < tbyte.Length; b++)


Then your code is very strange though:

for (int b = 1; b < tbyte.Length; b++)
{
tbyte.Initialize();
byte holding = (byte) bytebitmap.GetValue(b*a);
tbyte.SetValue(holding, b);
}

What do you expect that block to do?

It's clearing the array on every pass through the loop. I can't imagine
that's really what you want to do. Likewise calling SetValue is very
odd instead of using:

tbyte = holding;

I would think more carefully about what you really need to do, then
probably start from scratch.
 
Z

zacks

I am working with some images as byte[] arrays and am not sure nor can
I figure out if as I am reading the image and saving smaller sub-
images I am reading across and down the image or down and back up or
randomly? I need to know so in turn I can realize what the coordinates
are of the sub-images. Here is a snippet of the code that is
performing this task...

 for (int a = 1; a < 4800; a++) //will create 4800 sub images if a
goes to numsubimages
{
                Bitmap tempbitmap;
                //this declares the size of tbyte to be 768 which is
the number of bytes needed for 16x16 sub image
                byte[] tbyte = new byte[(stride * height) / ((height /
16) * (width / 16))];
                byte[] holding2 = new byte[tbyte.Length];

                for (int b = 1; b < tbyte.Length; b++)
                {
                    tbyte.Initialize();
                    byte holding = (byte) bytebitmap..GetValue(b*a);
                    tbyte.SetValue(holding, b);

                }
                tempbitmap = BytesToBmp(tbyte, tempSize); //save the
output of the 16x16 sub image so results can be seen

}

BytesToBmp is simply a function that coverts a byte array into a
bitmap image.

Thanks!

What is the input file type? I don't think this method would work for
a compressed image file like JPG.
 
S

Stephen.Schoenberger

I am working with some images as byte[] arrays and am not sure nor can
I figure out if as I am reading the image and saving smaller sub-
images I am reading across and down the image or down and back up or
randomly? I need to know so in turn I can realize what the coordinates
are of the sub-images. Here is a snippet of the code that is
performing this task...

My first reaction is that *twice* you've got an off by one error:
for (int a = 1; a < 4800; a++) //will create 4800 sub images

No, it won't. It will create 4799 - 1, 2, 3, 4... 4799.

In C# you almost always count from 0:

for (int a=0; a < 4800; a++)
...

You've got the same error later:

for (int b = 1; b < tbyte.Length; b++)

Then your code is very strange though:

for (int b = 1; b < tbyte.Length; b++)
{
tbyte.Initialize();
byte holding = (byte) bytebitmap.GetValue(b*a);
tbyte.SetValue(holding, b);
}

What do you expect that block to do?

It's clearing the array on every pass through the loop. I can't imagine
that's really what you want to do. Likewise calling SetValue is very
odd instead of using:

tbyte = holding;

I would think more carefully about what you really need to do, then
probably start from scratch.


Understand the errors. What I am trying to do is on each pass read
another 16x16 block from the image, store it (saved in other code not
shown), then move to the next block. The images I am working with are
JPEG's. I have done this method of using bytes to copy an entire image
to a new image but not sure how it progresses through the image.
 
J

Jon Skeet [C# MVP]

Understand the errors. What I am trying to do is on each pass read
another 16x16 block from the image, store it (saved in other code not
shown), then move to the next block. The images I am working with are
JPEG's. I have done this method of using bytes to copy an entire image
to a new image but not sure how it progresses through the image.

Well, you haven't shown exactly how BytesToBmp works, nor where you're
getting bytebitmap from. Without those bits of information, it's
impossible to say what's going on.
 
S

Stephen.Schoenberger

Well, you haven't shown exactly how BytesToBmp works, nor where you're
getting bytebitmap from. Without those bits of information, it's
impossible to say what's going on.

byte[] bytebitmap;
bytebitmap = BmpToBytes(bmpSource);

bmpSource is the 1280x960 bitmap that is read into the program via a
file dialog.

private unsafe Bitmap BytesToBmp(byte[] bmpBytes, Size
imageSize)
{
Bitmap bmp = new Bitmap(imageSize.Width,
imageSize.Height);

BitmapData bData = bmp.LockBits(new Rectangle(new Point(),
bmp.Size),
ImageLockMode.WriteOnly,
PixelFormat.Format24bppRgb);

Marshal.Copy(bmpBytes, 0, bData.Scan0, bmpBytes.Length);
bmp.UnlockBits(bData);
return bmp;
}

private unsafe byte[] BmpToBytes(Bitmap bmp)
{
BitmapData bData = bmp.LockBits(new Rectangle(new Point(),
bmp.Size),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);

int byteCount = bData.Stride * bmp.Height;
byte[] bmpBytes = new byte[byteCount];
Marshal.Copy(bData.Scan0, bmpBytes, 0, byteCount);
bmp.UnlockBits(bData);

return bmpBytes;
}
Thanks!
 
J

Jon Skeet [C# MVP]

bmpSource is the 1280x960 bitmap that is read into the program via a
file dialog.

Okay, so it's using LockBits, and I believe the format is always "first
row, second row, third row" etc while Stride is positive - although you
need to be careful if the unrounded width isn't a multiple of 4 bytes.

So, you've got a big byte array and you want to create lots of 256-byte
byte arrays. Let's concentrate on that and leave the actual bitmaps out
of the picture for the moment. I suggest you write a method with the
following signature:

byte[] CopyArea (byte[] data, int stride,
int desiredWidth, int desiredHeight,
int left, int top)

where "stride" in this case would be the same as the Stride of the
bitmap.

Hopefully the rest of the parameters and general intent are obvious -
have a go at implementing that and using it, and see where it leads
you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top