QPixmap copying sections, inverted coordinates help.
-
I am using a QPixmap to render an offscreen image which contains a lot of data, the image has a different coordinate system where 0,0 is bottom left.
The visual image has convention coordinate system 0,0 top left. The QPixmap is over 16000 pixels in height. The visual image has spinners associated with it that allow the user to set the minimum and maximum values which relate to the section of the QPixmap to display in the visual area.
I am struggling to get this right, I create an offscreen instance of QPixlmap:
//Work out the scale factor mszOffscreen = rctOffscreen.size(); //Create offscreen bitmap mpOffscreen = new QPixmap(mszOffscreen); //Fill background with transparent background mpOffscreen->fill(Qt::transparent);I then paint into this area, all of this is ok, I then invert the coordinate system:
//Create painter for rendering content QPainter objPainter(mpOffscreen); //Invert co-ordinate system so 0,0 is at he bottom QMatrix objOffscrMatrix; objOffscrMatrix.translate(0, intOffscreenSpan); objOffscrMatrix.scale(1, -1); objPainter.setMatrix(objOffscrMatrix);Now the bit I'm struggling with:
QRect rctSection; rctSection.setWidth(mszOnScreen.width()); int intAdjustment(truth::mspSlider->value() - 1); //Offscreen span contains everything, we need to apply the view minimum offset int intOnViewSpan((truth::msintViewMax - truth::msintViewMin + 1) * mptPixelsPerBSCAN.y()); intAdjustment += truth::msintViewMin - 1; //rctSection.setY(-(truth::msintViewMin - 1)); rctSection.setHeight(intOnViewSpan); if ( intAdjustment != 0 ) { rctSection.translate(0, -intAdjustment); } if ( imgStrip.isNull() != true ) { QImage imgSection(imgStrip.copy(rctSection)); if ( imgSection.isNull() != true ) { QImage imgScaled(imgSection.scaled(mszOnScreen)); if ( imgScaled.isNull() != true ) { objVisible.drawImage(QPoint(muint16Inset, muint16Inset), imgScaled); } } }When I adjust the minimum spinner the image looks ok and adjusts as I expect, the correct portion is displayed in the visual area, but when I adjust the maximum spinner it does not.
-
Fixed, no longer an issue.
QRect rctSection; int intOnscreenSpan((truth::msintViewMax - truth::msintViewMin) * mptPixelsPerBSCAN.y()), intYoffset(truth::msintViewMin * mptPixelsPerBSCAN.y()); intYoffset = intOnscreenSpan + intYoffset; rctSection.setRect(0, rctOffscreen.height() - intYoffset, mszOnScreen.width(), intOnscreenSpan); QImage imgSection(imgStrip.copy(rctSection)); -
I am using a QPixmap to render an offscreen image which contains a lot of data, the image has a different coordinate system where 0,0 is bottom left.
The visual image has convention coordinate system 0,0 top left. The QPixmap is over 16000 pixels in height. The visual image has spinners associated with it that allow the user to set the minimum and maximum values which relate to the section of the QPixmap to display in the visual area.
I am struggling to get this right, I create an offscreen instance of QPixlmap:
//Work out the scale factor mszOffscreen = rctOffscreen.size(); //Create offscreen bitmap mpOffscreen = new QPixmap(mszOffscreen); //Fill background with transparent background mpOffscreen->fill(Qt::transparent);I then paint into this area, all of this is ok, I then invert the coordinate system:
//Create painter for rendering content QPainter objPainter(mpOffscreen); //Invert co-ordinate system so 0,0 is at he bottom QMatrix objOffscrMatrix; objOffscrMatrix.translate(0, intOffscreenSpan); objOffscrMatrix.scale(1, -1); objPainter.setMatrix(objOffscrMatrix);Now the bit I'm struggling with:
QRect rctSection; rctSection.setWidth(mszOnScreen.width()); int intAdjustment(truth::mspSlider->value() - 1); //Offscreen span contains everything, we need to apply the view minimum offset int intOnViewSpan((truth::msintViewMax - truth::msintViewMin + 1) * mptPixelsPerBSCAN.y()); intAdjustment += truth::msintViewMin - 1; //rctSection.setY(-(truth::msintViewMin - 1)); rctSection.setHeight(intOnViewSpan); if ( intAdjustment != 0 ) { rctSection.translate(0, -intAdjustment); } if ( imgStrip.isNull() != true ) { QImage imgSection(imgStrip.copy(rctSection)); if ( imgSection.isNull() != true ) { QImage imgScaled(imgSection.scaled(mszOnScreen)); if ( imgScaled.isNull() != true ) { objVisible.drawImage(QPoint(muint16Inset, muint16Inset), imgScaled); } } }When I adjust the minimum spinner the image looks ok and adjusts as I expect, the correct portion is displayed in the visual area, but when I adjust the maximum spinner it does not.
-
@SPlatten Again: Avoid pointer abuse. It is not necessary to do it with QPixmap, it is enough with:
QPixmap mpOffscreen(mszOffscreen);Then
QPainter objPainter(&mpOffscreen);Also provide a minimal and reproducible example.
@eyllanesc , how is this pointer abuse? There is nothing wrong with the rendering the problem is when the spinners are used to adjust the data its calculating the correct offsets to get the right section of data that I need help with.
-
@eyllanesc , how is this pointer abuse? There is nothing wrong with the rendering the problem is when the spinners are used to adjust the data its calculating the correct offsets to get the right section of data that I need help with.
@SPlatten Please read https://en.wikipedia.org/wiki/Memory_leak. Many developers use the memory of the heap (pointers) without understanding how to handle them and their limitations. The general rule of thumb: If you don't need pointers then don't use them.
My first observation is not trying to fix the problem but to point out the underlying problems that can cause silent bugs.
My second observation (that of the minimal example) I point it out since I need more information, I need to test to try to give you a diagnosis.
-
@SPlatten Please read https://en.wikipedia.org/wiki/Memory_leak. Many developers use the memory of the heap (pointers) without understanding how to handle them and their limitations. The general rule of thumb: If you don't need pointers then don't use them.
My first observation is not trying to fix the problem but to point out the underlying problems that can cause silent bugs.
My second observation (that of the minimal example) I point it out since I need more information, I need to test to try to give you a diagnosis.
@eyllanesc I do need the pointer that is why its created, the offscreen map is created once at start-up, not every time its painted. Please don't try to tell me how to use pointers, this isn't the issue and I'm an very experienced coder.
-
@eyllanesc I do need the pointer that is why its created, the offscreen map is created once at start-up, not every time its painted. Please don't try to tell me how to use pointers, this isn't the issue and I'm an very experienced coder.
-
@SPlatten Well, it seems you haven't learned some basic memory management rules. Please avoid pointing out that we can (or not) comment, in the same way that you can ask us, we can comment. Goodbye, I'll go my way.
@eyllanesc , how can you make such comments without seeing the rest of the code?
-
I'm still working on this problem, can anyone help? To summarise I have an offscreen bit map where the origin is bottom left.
See my first post in this thread for details. I have spinners to set the offset and amount to view in the visible area. The visible area has its origin top left. I am having difficulty copying the correct area from the offscreen image to the visible image.
Here is the latest code:
//Create painter for rendering content QPainter objPainter(mpOffscreen); //Invert co-ordinate system so 0,0 is at he bottom QMatrix objOffscrMatrix; objOffscrMatrix.translate(0, intOffscreenSpan); objOffscrMatrix.scale(1, -1); objPainter.setMatrix(objOffscrMatrix); //Draw onto offscreen painter ... //Restore the context objPainter.restore(); //Produce an image from the offscreen map QImage imgStrip(mpOffscreen->toImage()); //Create painter for visible rendering QPainter objVisible(this); objVisible.fillRect(rctWorking, mclrBG); //This is the bit that needs work... QRect rctSection; rctSection.setWidth(mszOnScreen.width()); int intAdjustment(truth::mspSlider->value() - 1); intAdjustment += truth::msintViewMin - 1; intAdjustment *= mptPixelsPerBSCAN.y(); //Offscreen span contains everything, we need to apply the view minimum offset uint uintOnView((truth::msintViewMax - truth::msintViewMin + 1) * mptPixelsPerBSCAN.y()); rctSection.setHeight(uintOnView); if ( intAdjustment != 0 ) { rctSection.setY(intAdjustment);// translate(0, rctWorking.height() - intAdjustment);//-intAdjustment); }When the view is set to contain everything, it works perfectly and the offscreen image is scaled and copied to the visible area. If I set the minimum and maximum to copy a section of the offscreen image then its not correct and I'm struggling to see what I need to do. Is there some kind of translation or transformation that should be performed between the offscreen and onscreen images which have different coordinate systems?
Thank you.
-
Fixed, no longer an issue.
QRect rctSection; int intOnscreenSpan((truth::msintViewMax - truth::msintViewMin) * mptPixelsPerBSCAN.y()), intYoffset(truth::msintViewMin * mptPixelsPerBSCAN.y()); intYoffset = intOnscreenSpan + intYoffset; rctSection.setRect(0, rctOffscreen.height() - intYoffset, mszOnScreen.width(), intOnscreenSpan); QImage imgSection(imgStrip.copy(rctSection));