Hi guys, I am trying to work on something where I set an image in a picturebox and then use getpixel to scan the whole image and find the percentage of the colour I am interested in, in that image.

The problem is that if the image is large then the program hangs, it only works for count of co-ordinates upto (50,50) even then it takes a few seconds to write the results in the text box. I have read on LockBits method but I dont understand how to use it properly on the picturebox as I am new to C++. Can anyone give me an example on how to go about doing this or are there any better alternatives as I will be using this program on microscope images which have a pretty high resolution probably around 1080p or more ?

` int RequiredCount, nonRequiredCount, CountPerc;

Image^ i = pictureBox1->Image;  

Bitmap^ b = gcnew Bitmap(i);  

For (int y = 0; y < (pictureBox1.Height - 1), y++)
{
    For (int x = 0; x < (pictureBox1.Width - 1), x++)
        {

            Color c = b->GetPixel(x,y);
            int k, j, z;

            k = c.R;
            j = c.G;
            z = c.B;

            if (k <= 75 && j <= 75 && z <= 75) 
             {
                    this->txt1->Text = this->txt1->Text + " | " + c.R.ToString() + "-" + c.G.ToString() + "-" + c.B.ToString(); 
                    RequiredCount = RequiredCount + 1;
              }
            else
              {
                    nonRequiredCount = nonRequiredCount + 1;
              }

            CountPerc = (RequiredCount / nonRequiredCount) * 100;
            this->btnWork->Text = CountPerc.ToString();


        }

} `

Thank you.

Recommended Answers

All 3 Replies

Check out some of these articles. Most are for C# but they should apply to CLR/C++ as well. You should bookmark that site because they have the largest repository of free code/examples on the net for MS-Windows programming.

You can use these GDI API functions:

GetObject
GetDIBits

They are faster than GetPixel but entails more work than the latter.

I have read on LockBits method but I dont understand how to use it properly on the picturebox as I am new to C++. Can anyone give me an example on how to go about doing this

An example of using LockBits.....

// test.cpp
// Compile cl /CLR test.cpp

#include <windows.h>

#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>

using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;

public ref class myTest : public Form
{
private:
    PictureBox ^ pctBox;

public:
    myTest()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        pctBox = gcnew PictureBox;
        pctBox->Location = Point(10, 10);
        pctBox->Size = System::Drawing::Size(1200, 1550);

        Controls->Add(pctBox);
        Bitmap^  pImage = gcnew Bitmap("c:\\temp\\my24bit.bmp", true);
        pctBox->Image = pImage; 

        // Lock the bitmap's bits.
        System::Drawing::Rectangle rect = System::Drawing::Rectangle(0,0,pImage->Width,pImage->Height);
        System::Drawing::Imaging::BitmapData^ bmpData = pImage->LockBits( rect, System::Drawing::Imaging::ImageLockMode::ReadWrite, pImage->PixelFormat );

        // Get the address of the first line.
        IntPtr ptr = bmpData->Scan0;

        // Declare an array to hold the bytes of the bitmap.
        // This code is specific to a bitmap with 24 bits per pixels.
        int bytes = Math::Abs(bmpData->Stride) * pImage->Height;
        array<Byte>^rgbValues = gcnew array<Byte>(bytes);

        // Copy the RGB values into the array.
        System::Runtime::InteropServices::Marshal::Copy( ptr, rgbValues, 0, bytes );

        // Set every ninth value to 255.
        for ( int counter = 8; counter < rgbValues->Length; counter += 9 )
            rgbValues[ counter ] = 255;

        // Copy the RGB values back to the bitmap
        System::Runtime::InteropServices::Marshal::Copy( rgbValues, 0, ptr, bytes );

        // Unlock the bits.
        pImage->UnlockBits( bmpData );

        // Draw the modified image.
        pctBox->Image=pImage;
    }
};


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine,
                     int nCmdShow)
{
    Application::Run(gcnew myTest());
    return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.