一种列出砖块的字节像素值的方法

发布于 2024-12-11 03:45:44 字数 2368 浏览 0 评论 0原文

抱歉,我不知道如何设置一个主题来表达我需要什么帮助。

我有一个字节数组,其中包含位图中每个像素的值。它是一个一维数组,从左到右。它获取每一行并将其添加到数组索引的末尾。

我想将位图分割为 225(=15*15) 块。例如,每个砖块的尺寸为 34x34,则数组的长度为 260100(=225*34*34)。正如您现在所看到的,我们需要 15 块宽度和高度的砖块。

几个月前,我使用了从 0 到 14 的两个循环。我编写了自己的长代码来获取所有 34x34 的砖块。但是我没有使用任何存储所有值的数组。

现在我有一个一维数组,因为带位锁的编组复制和位图数据是将所有像素值快速复制到数组的最佳方法。

但我面临的问题是如何获得 34 个元素,然后再降低一行,并知道在 35 层将是另一块具有自己起始值的砖块。

PS。如果有什么不好的,请编辑我的帖子。

很少有人会说“首先编写测试代码”。我尝试过,但得到的只是垃圾,我真的不知道该怎么做。


该方法用于将图像裁剪为包含砖块的较小图像。但我不想存储砖块的小图像。我需要将值存储在字节数组中。

下面,有一个证明。

private void OCropImage(int ii, int jj, int p, int p2)


   {
        ////We took letter and save value to binnary, then we search in dictionary by value
        this.rect = new Rectangle();
        this.newBitmap = new Bitmap(this.bitmap);
        for (ii = 0; ii < p; ii++)
        {
            for (jj = 0; jj < p2; jj++)
            {
                ////New bitmap
                this.newBitmap = new Bitmap(this.bitmap);

                ////Set rectangle working area with letters
                this.rect = new Rectangle(jj * this.miniszerokosc, ii * this.miniwysokosc, this.miniszerokosc, this.miniwysokosc);
                ////Cut single rectangle with letter
                this.newBitmap = this.newBitmap.Clone(this.rect, this.newBitmap.PixelFormat);
                ////Add frame to rectangle to delet bad noise
                this.OAddFrameToCropImage(this.newBitmap, this.rect.Width, this.rect.Height);
                this.frm1.SetIm3 = (System.Drawing.Image)this.newBitmap;

                ////Create image with letter which constains less background
                this.newBitmap = this.newBitmap.Clone(this.GetAreaLetter(this.newBitmap), this.newBitmap.PixelFormat);
                ////Count pixels in bitmap
                this.workingArea = this.GetBinnary(this.newBitmap);

                var keysWithMatchingValues = this.alphabetLetters.Where(x => x.Value == this.workingArea).Select(x => x.Key);
                foreach (var key in keysWithMatchingValues)
                {
                    this.chesswords += key.ToString();
                }
            }

            this.chesswords += Environment.NewLine;
            var ordered = this.alphabetLetters.OrderBy(x => x.Value);
        }
    }

PS2。抱歉我的英语,如果需要的话请纠正。

Sorry I had no idea how set a topic which could express what help I need.

I have in an array of bytes, values for each pixel from a bitmap. It is a one dimensional array, from left to right. It takes each row and add it to the end of array's index.

I would like to split a bitmap to 225(=15*15) pieces. Each brick has for example dimension 34x34 and the length of array is then 260100(=225*34*34). So as you see now we will need 15 bricks on width and on height.

Few months ago I was using two loops starting from 0 - 14. I wrote own long code to get all that 34x34 bricks. However I didn't used any array which was storing all values.

Now I have a one dimensional array because marshal copy and bitmapdata with bitlocks were the best way to fast copy all pixels' values to array.

But I stand face to face with problem how to get 34 elements then one row lower and another one knowing that on 35 level will be another brick with its own starting value..

PS. edit my post if something is not good.

Few people could say "first make any your test code". I tried that but what I got was just trash and I really don't know how to do that.


This method was used to crop image to smaller images containing bricks. But I don't want store small images of brick. I need values storing in array of bytes.

Under, there is a proof.

private void OCropImage(int ii, int jj, int p, int p2)


   {
        ////We took letter and save value to binnary, then we search in dictionary by value
        this.rect = new Rectangle();
        this.newBitmap = new Bitmap(this.bitmap);
        for (ii = 0; ii < p; ii++)
        {
            for (jj = 0; jj < p2; jj++)
            {
                ////New bitmap
                this.newBitmap = new Bitmap(this.bitmap);

                ////Set rectangle working area with letters
                this.rect = new Rectangle(jj * this.miniszerokosc, ii * this.miniwysokosc, this.miniszerokosc, this.miniwysokosc);
                ////Cut single rectangle with letter
                this.newBitmap = this.newBitmap.Clone(this.rect, this.newBitmap.PixelFormat);
                ////Add frame to rectangle to delet bad noise
                this.OAddFrameToCropImage(this.newBitmap, this.rect.Width, this.rect.Height);
                this.frm1.SetIm3 = (System.Drawing.Image)this.newBitmap;

                ////Create image with letter which constains less background
                this.newBitmap = this.newBitmap.Clone(this.GetAreaLetter(this.newBitmap), this.newBitmap.PixelFormat);
                ////Count pixels in bitmap
                this.workingArea = this.GetBinnary(this.newBitmap);

                var keysWithMatchingValues = this.alphabetLetters.Where(x => x.Value == this.workingArea).Select(x => x.Key);
                foreach (var key in keysWithMatchingValues)
                {
                    this.chesswords += key.ToString();
                }
            }

            this.chesswords += Environment.NewLine;
            var ordered = this.alphabetLetters.OrderBy(x => x.Value);
        }
    }

PS2. sorry for my English, please correct it if it is needed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

策马西风 2024-12-18 03:45:44

如果我的理解是对的,那么如果你有一个像这样的图像

p00|p01|p02|...
---+---+-------
p10|p11|p12|...
---+---+-------
p20|p21|p22|...
---+---+---+---
...|...|...|...

,它存储在从左到右行扫描的数组中,如下所示:

p00,p01,...,p0n, p10,p11,...,p1n, p20,p21, ...

如果我理解正确,你想要做的就是采取图像中给定的矩形(来自具有特定宽度和高度的特定 x 和 y)。下面是执行此操作的代码,并附有解释:

byte[] crop_area (byte[] source_image, int image_width, int image_height,
int start_x, int start_y, int result_width, int result_height)
{
    byte[] result = new byte[result_width * result_height];
    int endX = x + result_width;
    int endY = y + result_height;

    int pos = 0;

    for (int y = startY; y < endY; y++)
        for (int x = startX; x < endX; x++)
        {
            /* To get to the pixel in the row I (starting from I=1), we need
             * to skip I-1 rows. Since our y indexes start from row 0 (not 1),
             * then we don't need to subtract 1.
             *
             * So, the offset of the pixel at (x,y) is:
             *
             *     y * image_width      +        x
             * |-----------------------| |-----------------|
             *   Skip pixels of y rows    Offset inside row
             */
            result[pos] = source_image[y * image_width + x];

            /* Advance to the next pixel in the result image */
            pos++;
        }
    return result;
}

然后,要获取 I 行 J 列 (I,J=0,...,14) 中的块,请执行以下操作:

crop_area (source_image, image_width, image_height, J*image_width/15, I*image_height/15, image_width/15, image_height/15)

If I get you right, then if you have an image like this

p00|p01|p02|...
---+---+-------
p10|p11|p12|...
---+---+-------
p20|p21|p22|...
---+---+---+---
...|...|...|...

Which is stored in an array in left-to-right row scan like this:

p00,p01,...,p0n, p10,p11,...,p1n, p20,p21, ...

If I understand you correctly, what you want to be able to do, is to take a given rectangle (from a certain x and y with a certain width and height) from the image. Here is code to do this, with explanations:

byte[] crop_area (byte[] source_image, int image_width, int image_height,
int start_x, int start_y, int result_width, int result_height)
{
    byte[] result = new byte[result_width * result_height];
    int endX = x + result_width;
    int endY = y + result_height;

    int pos = 0;

    for (int y = startY; y < endY; y++)
        for (int x = startX; x < endX; x++)
        {
            /* To get to the pixel in the row I (starting from I=1), we need
             * to skip I-1 rows. Since our y indexes start from row 0 (not 1),
             * then we don't need to subtract 1.
             *
             * So, the offset of the pixel at (x,y) is:
             *
             *     y * image_width      +        x
             * |-----------------------| |-----------------|
             *   Skip pixels of y rows    Offset inside row
             */
            result[pos] = source_image[y * image_width + x];

            /* Advance to the next pixel in the result image */
            pos++;
        }
    return result;
}

Then, to take the block in the row I and column J (I,J=0,...,14) do:

crop_area (source_image, image_width, image_height, J*image_width/15, I*image_height/15, image_width/15, image_height/15)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文