Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dividing QImage to smaller pieces

I have an image, and I want to divide this image to n pieces. So what I'm wondering is that how can I do this with QImage? Or is there a better(performance wise) Qt class for this task?

For example imagine I have an image consist of 1920x1080 pixels, and I want to divide it to 100 pieces which means each piece will consist of 192x108 pixels. Note that I don't want to create same piece scaled to 192x108. Each piece is a distinct piece of the main picture.

enter image description here

I have attached an Image to make my question clearer. This image consist of 1920x1080 pixels and each part dived with grids consists of 192x108 pixels, I want to treat each of them as QImage object without actually dividing it to 100 pieces.

Is there a way to do this with QImage? Performance is important here because I'll analyze each piece and usually there is going to be more than 1000 piece.

Thank you for your help!

EDIT: Both methods work perfectly, however alexisdm's method is bit more complex, lower-level, but faster. jmk's method is easier to use but it's slower.

Thanks for both answers.

like image 598
Malkavian Avatar asked Oct 01 '12 21:10

Malkavian


3 Answers

You can create a QImage without copying any data by using the same stride (bytes per line) and format as the source image and passing the raw data buffer, with an offset corresponding to the desired starting position, to one of the constructors of QImage:

QImage createSubImage(QImage* image, const QRect & rect) {
    size_t offset = rect.x() * image->depth() / 8
                    + rect.y() * image->bytesPerLine();
    return QImage(image->bits() + offset, rect.width(), rect.height(),
                  image->bytesPerLine(), image->format());
}

The source image must exist as long as the sub QImage exists.

But it might not work if the analyzing code tries to access the image raw data directly without using QImage::bytesPerLine(), QImage::scanLine() or QImage::pixel().

like image 81
alexisdm Avatar answered Nov 19 '22 10:11

alexisdm


You can accomplish this by creating new QImage objects of the desired dimensions, then drawing the appropriate pieces of the source image into them. To do this, create a QPainter from the empty target image, and use the drawImage() method to copy a specific sub-rectangle.

If performance is important, however, you might want to look at ways to avoid unnecessary copies of your source image. For example, if your algorithm only needs to look at a 192x108 piece of the picture at a time, could it just limit its analysis to a particular sub-rectangle of the original image?

If you can restructure your code this way, you can avoid creating additional images entirely.

like image 42
jmk Avatar answered Nov 19 '22 10:11

jmk


You can use built-in function QImage QImage::copy(const QRect &part) that creates subimage.

like image 3
trig-ger Avatar answered Nov 19 '22 09:11

trig-ger