Checking that the image is empty in C #

I looked everywhere, but there seemed to be no standard (I could see) how one could check if the image was blank. In c #

I have a way to do this, but I would really like to know what is the right way to check if the image is empty, so everyone can know in the future.

I'm not going to copy paste a bunch of code, if you want it, I will be pleased, but I just want to explain how I can check if the image is empty.

You take a .jpg image, get its width. For example, 500 pixels Then you divide it by 2 giving you 250

Then you check what color of each pixel is in place (width 250 and height i) (where you repeat the thought of image height.

What this means is only checking the center line of the image pixels vertically. It looks like all the pixels are checking to see if there is any color other than white. I did this, so you don’t have to search ALL 500 * pixel heights, since you almost always encounter color in the middle of the page.

His work ... a little slow ... Should there be a better way to do this? You can change it to search 2/3/4 lines vertically to increase the likelihood that the page will not be blank, but it will take even longer.

(Also note: using the image size to verify that it contains something will not work in this case, since the page with two sentences and the empty page size are too close to each other)

After adding the solution.

Resources that will help in the implementation and understanding of the solution.

(Note that on the first website, the claimed Pizelformat is actually Pixelformat). The little mistake that I know, just mentioning, can cause some confusion for some.

After I implemented the method of accelerating the search for pixels, the speed did not increase. Therefore, I think that I am doing something wrong.

Old time = 15.63 for 40 images.

New time = 15.43 for 40 images

I saw with a large DocMax quoted article that the code is "blocked" in a set of pixels. (or, as I understand it) So, I did a lock in the middle row of pixels of each page. Will this be the right step?

private int testPixels(String sourceDir) { //iterate through images string[] fileEntries = Directory.GetFiles(sourceDir).Where(x => x.Contains("JPG")).ToArray(); var q = from string x in Directory.GetFiles(sourceDir) where x.ToLower().EndsWith(".jpg") select new FileInfo(x); int holder = 1; foreach (var z in q) { Bitmap mybm= Bitmap.FromFile(z.FullName) as Bitmap; int blank = getPixelData2(mybm); if (blank == 0) { holder = 0; break; } } return holder; } 

And then the class

 private unsafe int getPixelData2(Bitmap bm) { BitmapData bmd = bm.LockBits(new System.Drawing.Rectangle((bm.Width / 2), 0, 1, bm.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bm.PixelFormat); int blue; int green; int red; int width = bmd.Width / 2; for (int y = 0; y < bmd.Height; y++) { byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride); blue = row[width * 3]; green = row[width * 2]; red = row[width * 1]; // Console.WriteLine("Blue= " + blue + " Green= " + green + " Red= " + red); //Check to see if there is some form of color if ((blue != 255) || (green != 255) || (red != 255)) { bm.Dispose(); return 1; } } bm.Dispose(); return 0; } 
+6
source share
3 answers

If you can tolerate being mistaken, the approach seems fine; I did something very similar in my case, although I always had visual confirmation to fix the errors.

For performance, the key question is how you get pixels for testing. If you use Bitmap.GetPixel , you will have performance issues. (Search for “ Bitmap.GetPixel slow ” on Google to see a lot of discussion.)

Further performance will be achieved by obtaining all the pixels at the same time, and then looping on them. I personally like the Bob Powell LockBits discussion for clarity and completeness. With this approach, checking all pixels may be reasonable depending on your performance needs.

+7
source

If you use System.Drawing.Bitmap, you can speed up the process (essentially) by using:

  • Without using GetPixel to access pixels, use LockBits and UnlockBits to copy the bitmap image to regular memory. See the examples in the MSDN documentation for use.
  • Do not invoke width, height, or size properties in a loop. Call once, save the values ​​in a local variable and use them in a loop.

Notes:

  • When using System.Drawing.Bitmap, your image may be in the device’s memory and it may take a long time to access it.
  • I don’t remember whether the image loads into a bitmap image in the RGB format, since it is more difficult to work with other formats, but if it is not, you can create an RGB bitmap of the same size as your original image, get its graphic object (Graphics. FromImage) and use DrawImage to draw the source image in an RGB bitmap.

Edit: Hit DocMax.

In any case, for speed, you can also try using alternative libraries, such as the excellent FreeImage , which includes C # shells.

+2
source

Scale the image to 1x1, then check one pixel

new bitmap (previousImage, new size (1, 1));

0
source

Source: https://habr.com/ru/post/926725/


All Articles