Hello high Skilled Programmers
I have a test image 1600x1600. I imported this to a matrix as grayscale int values. Then i created 4x4 sub matrixes from that matrix.I made some math operations in these blocks and created new blocks. Now i need to create a new matrix again (1600x1600) from that new 4x4 blocks.But i couldnt create the loop. I Have (1600/4 * 1600/4 = 160 000) sub matrixes totaly. (Of course my program is not static , the input image can be anything.This is for test image). Now this is my structure.
Bitmap bmp = new Bitmap("c:\\test.jpg");
pictureBox1.Image = Image.FromFile("c:\\test.jpg");
int width = bmp.Width; int height = bmp.Height;
while (y < height) {
while (x < width) {
pxl = bmp.GetPixel(x, y);
int_grayscale_map[x, y] = GetGrayScale(pxl); //getgrayscale is function that returns int value
x++;}
y++;}
int totalblocknumber = (width/4) * (height / 4); //160 000 in this case
Now I created and populated the sub blocks from this codes. Someone helped me here.(think that we puzzled the 1600x1600 image to 4x4 pieces)
Bitmap image = new Bitmap(FILENAME);
List<List<List<Int32>>> grayscale_map_block = newList<List<List<Int32>>>();
for (int row = 0; row < height; row += 4)
{
for (int col = 0; col < width; col += 4)
{
block.Add(new List<List<Color>>() {
new List<Color>() { image.GetPixel(col, row), image.GetPixel(col + 1, row), image.GetPixel(col + 2, row), image.GetPixel(col + 3, row)} ,
new List<Color>() { image.GetPixel(col, row + 1), image.GetPixel(col + 1, row + 1), image.GetPixel(col + 2, row + 1), image.GetPixel(col + 3, row + 1)} ,
new List<Color>() { image.GetPixel(col, row + 2), image.GetPixel(col + 1, row + 2), image.GetPixel(col + 2, row + 2), image.GetPixel(col + 3, row + 2)} ,
new List<Color>() { image.GetPixel(col, row + 3), image.GetPixel(col + 1, row + 3), image.GetPixel(col + 2, row + 3), image.GetPixel(col + 3, row + 3)} ,
});
grayscale_map_block.Add(new List<List<Int32>>() {
new List<Int32>() { GetGrayScale(image.GetPixel(col, row)), GetGrayScale(image.GetPixel(col + 1, row)), GetGrayScale(image.GetPixel(col + 2, row)), GetGrayScale(image.GetPixel(col + 3, row))} ,
new List<Int32>() { GetGrayScale(image.GetPixel(col, row + 1)), GetGrayScale(image.GetPixel(col + 1, row + 1)), GetGrayScale(image.GetPixel(col + 2, row + 1)), GetGrayScale(image.GetPixel(col + 3, row + 1))} ,
new List<Int32>() { GetGrayScale(image.GetPixel(col, row + 2)), GetGrayScale(image.GetPixel(col + 1, row + 2)), GetGrayScale(image.GetPixel(col + 2, row + 2)), GetGrayScale(image.GetPixel(col + 3, row + 2))} ,
new List<Int32>() { GetGrayScale(image.GetPixel(col, row + 3)), GetGrayScale(image.GetPixel(col + 1, row + 3)), GetGrayScale(image.GetPixel(col + 2, row + 3)), GetGrayScale(image.GetPixel(col + 3, row + 3))} ,
});
}
} // Getgrayscale is a function that input color return int value
All that is. Now i have 160 000 piece of 4x4 matrix caled "grayscale_map_block" i am using this code to get the element of the blocks grayscale_map_block [n] [x] [y] / n'th block , x,y element. where n =0-totalblocknumber
From that blocks i must smartly create a loop that get pieces together. A new 1600x1600 matrix. Thanks for your helps..
Here is an example of accessing a 2D array with a different indexing mechanism. Here n
is the block number and x
and y
are the 0-3 indices within the 4x4 block. This just remaps (n,x,y) to (xx,yy) which are the indices of the data in the original 2D array.
class BlockData
{
public int[,] data;
internal void reindex(int n, int x, int y, out int xx, out int yy)
{
const int blockSize = 4;
int width = data.GetLength(0);
int columns = width / blockSize;
int row = n / columns;
int col = n % columns;
xx = col * blockSize + x;
yy = row * blockSize + y;
}
public int this[int n, int x, int y]
{
get
{
int xx, yy;
reindex(n, x, y, out xx, out yy);
return data[xx, yy];
}
set
{
int xx, yy;
reindex(n, x, y, out xx, out yy);
data[xx, yy] = value;
}
}
public int this[int xx, int yy]
{
get
{
return data[xx, yy];
}
set
{
data[xx, yy] = value;
}
}
}
class Program
{
static void Main(string[] args)
{
BlockData b = new BlockData() { data = new int[1600, 1600] };
b[10, 5] = 999;
// (10,5) is in the 402nd block of 4x4 at (2,1) within that block.
Debug.Assert(b[402, 2, 1] == 999);
b[888, 3, 2] = 777;
// The 888th block is row 2, column 88. Its top-left is at ((88*4),(2*4)).
// (352 + 3, 8 + 2) = (355, 10)
Debug.Assert(b[355, 10] == 777);
}
}
Using the same strategy, you could store your data internally as a 1D array too and provide different index mappings from [n][x][y] to just a linear [i].
Providing an object with an array index operator is really just "cute". It's not necessary. The idea is just to do the math to calculate the indices of your source data you want to access. But it helps illustrate my point.
(Performance note: You could optimize this so that blockSize
, width
, and columns
are precomputed when you initialize data
if you wanted to speed up access time and avoid calling data.GetLength(0)
all the time.)