undo setPixel operation in qt by moving Slider - c++

i have an application in qt that loads an image. The user can set a cross by moving the slider with setPixel(). If he decrements the slider, the cross should become smaller and the original pixel should be displayed.
But unfortunately nothing happens when I decrement the slider. The cross keeps its maximum size.
The function, that sets the Pixel
void ImageViewer::applyExampleAlgorithm(int kreuzBreite)
{
if(image!=NULL)
{
for(int i=0;i<((kreuzBreite*std::min(image->width(), image->height())/ 100) / 2);i++)
{
image->setPixelColor(image->width()/2+i,image->height()/2,QColor(255,0,0,0));
image->setPixelColor(image->width()/2-i,image->height()/2,QColor(255,0,0,0));
image->setPixelColor(image->width()/2,image->height()/2+i,QColor(255,0,0,0));
image->setPixelColor(image->width()/2,image->height()/2-i,QColor(255,0,0,0));
}
}
updateImageDisplay();
renewLogging();
}
My Slider
QSlider *slider1 = new QSlider(Qt::Horizontal,0);
slider1->setRange(0,100);
connect(slider1, SIGNAL(valueChanged(int)),this, SLOT(applyExampleAlgorithm(int)));
As you can see, the value changes, but my cross does not.
I think I have to save the original pixel and rewrite it, as soon as the red cross disappears at this point. But I dont really know how.

When the slider value decreases, your function only "draw" a smaller red cross in the bigger one that was drawn before. You can store the original image in a different variable. Then, before drawing the red cross, restore to the original image.

Related

osmdroid: animate to current location with pixel offset

I am trying to achieve an effect like Google Maps and many other (all?) navigation apps: in navigation mode, the current location is displayed at the bottom of the screen, so that the user can see more of the road in front of them.
I already have the code to update the location and also change the map's orientation based on the bearing. Everything works perfectly if I keep the map centered on the location, so I am moving on to the offset part. Here is what I have:
if (followMe) {
float bearing = [...]; // OK until here
mapView.getController().setCenter(currentLocation); // quickly center on location
mapView.getController().scrollBy(0, -(int)(mapView.getHeight() / 2 * 0.8)); // shift
GeoPoint newCenter = mapView.getProjection().getCurrentCenter(); // get the coordinates of the new center
mapView.getController().animateTo(newCenter, null, (long) 1000, bearing); // center again, this time with a nice animation
}
It does not work as intended and produces weird behaviors: the map is centered elsewhere entirely, updates all of a sudden, etc. I suspect it's because of things like sudden changes in the bearing, or maybe I am just getting it wrong.
Any suggestions?

Osmdroid - Marker - increase selection area to get the InfoWindow

When selecting a Marker an InfoWindow pops up.
Sometimes the selection of a Marker is difficult. Especially when the map is rotating in the direction of navigation.
How can I increase the 'touch circle' so that selection is easier?
Update: I have to change the hitTest() for the Marker by subclassing.
I would like to check whether the 'hit' (or touch) was within a circle of X pixels around the point of the Marker. The icon will rotate while I navigate, so I guess I don't use the icon.
How can I do that?
public boolean hitTest(final MotionEvent event, final MapView mapView){
final Projection pj = mapView.getProjection();
pj.toPixels(mPosition, mPositionPixels);
// Does mPositionPixels contains the x, y of the Marker?
// Should I draw a Rect around this point, or could it be a circle?
// How can I check whether the event.getX(), event.getY() is a hit?
return hit;
}
Method proposed by spy is feasible.
You can also create your icon bitmap with an area of transparent pixels around. This is a very simple way to increase its touch area.
I believe #Mker would say, extend the Marker class and override the method hitTest. That is used for the Marker itself. I'm not sure if you can change this for the InfoWindow itself.

Progressbar - Smooth transition between percentages

I'm trying to program my own progressbar and this I already got working. Each time the percent value changes the bar changes too, so that the bar displays the right progress.
Now my problem is, that the bar always (of course) jumps to the next state and there is no smooth transition between it. Now my question is, how can I make a smooth transition between the stages?
Informations:
I know the fpscount of the game and the position + scale of the bar. And I'm programming in java (I think this information is unnecessary :P)
A general answer, not language specific.
Instead of directly setting the width, you could increase each frame the width until its the desired width/percentage.
Let's assume you have the function bar.setWidth(val) to set the width of your progress bar.
Let this be your update loop (ran at 60FPS):
update {
...
...
double percentageLoaded; // this is your parameter probably
static const int incrementStep = 1; // increase this for faster animation
// Get the width of the bar for the current percentage
int desiredWidth = percentageLoaded * bar.totalWidth;
if(bar.currentWidth < desiredWidth) {
bar.currentWidth += incrementStep;
}
}
There are still a few things you have to check if your incrementStep is larger than 1. (eg: don't set the bar width larger than 100%)
Here is a small drawing, maybe it helps you understand better. In this example the increment step is 1px, the bar width is 4px and the loading was set to be 50% complete, this means that your bar should be 2px in width.

How to show part of an image using QT?

So, this is my problem: I have this very big image, and I want to show only a specific part of it. After the user pressing a specific key I want the image to move, showing another part of it. The transition from one part of the image to another have to be smooth, animated.
I tried using a QLabel to show the image but it always shows the center of the image, and I do not really know how to make the animation. What would you guys suggest?
Interesting question. Here is something I just tested and seems to work.
Add a QGraphicsView with dimensions the dimensions of the part of the image you want to display, eg 100x100. Create a QGraphicsScene and add it to the view:
QGraphicsScene* pScene = new QGraphicsScene(this);
ui->graphicsView->setScene(pScene);
Now add your image into the scene. In my case I has an image in my resource file. The trick is to set the sceneRect to the position you want to display. I wanted to display an 100x100 part of the image starting from 0,300 :
pItem = pScene->addPixmap(QPixmap::fromImage(QImage(":/photos/image")));
pScene->setSceneRect(0,300,100,100);
In order to test the smooth moving I added a button which when clicked is triggering a slot called move. This slot simply updates the sceneRect. In my simple example I just move the image 100 pixels right. In a real world scenario you could also move it diagonally or vertically and check the image limits.
void move()
{
for (unsigned i=currentX; i<currentX + 100; i++)
{
ui->graphicsView->scene()->setSceneRect(i,300,100,100);
qApp->processEvents();
}
currentX += 100;
}
Notice the currentX variable. It is nothing more than the last image position. Also we must call the processEvents in order to "see" the image moving smoothly.
You could use QPixmap::copy( int x, int y, int width, int height ) to copy a region of the image and display that.
Few options:
Try using a Q3CanvasSprite (within in a Q3Canvas). It is designed more for splitting one image into multiple ones but not for animating between them. You could try abusing it and declaring (say) 100 frames (10 per digit, which would be used as animation steps) or just use the move() method.
Try QGraphicsPixmapItem::setOffset() (within a QGraphicsScene). This might be overkill as QGraphicsScene is made for large number of images).
I'm not sure, but maybe this can be done with QStateMachine and QAbstractAnimation.

QGraphicsItem::setTransformOriginPoint bug when trying to scale image

I have created my own class by extending QGraphicsItem and I want to make it so that when someone does a wheel even while over this item, it scales.
This way, i can have multiple items in a scene, and scale each of them in and out as I please.
The problem is, I want the item to scale under the mouse cursor, much like google maps does. That is, a move forward will keep panning the image and scaling it, so taht the area in the vicinity around my mouse pointer is always in view.
void ImagePixmapItem::wheelEvent ( QGraphicsSceneWheelEvent * event ){
update();
qreal factor = 1.2;
if (event->delta() < 0)
factor = 1.0 / factor;
scale(factor, factor);
scaleFactor *=factor;
this->scene()->setSceneRect(0,0,this->boundingRect().width(), this->boundingRect().height());
}
This is the code I am using to do the scale. The problem is, it always seems to be scaling from the top left corner. Well, this is undesirable, beacuse if I scale in or out too much, eventually my area of interest around the mouse pointer has moved off the screen, and I have to either scroll manually or pan to the location, zoom, pan, etc, until i get to the desired level.
I tried to use the QGraphicsItem::setTransformOriginPoint, but no matter what values I put in there, it still seems to scale and such from the top left.
What can I add to that code I posted to get the desired effect?
I have achieved similar functionality in my Image-Manipulation application (scaling the view and having the area under my mouse stay in place and visible) but I scale the whole graphics-view not a specific item, so I don't know if this code can solve your problem.
Anyway, this is what I do in the constructor of my subclassed QGraphicsView (after I set the scene):
setTransformationAnchor(AnchorUnderMouse);
setResizeAnchor(AnchorViewCenter);
I also use the above functions, after each call to:
MyGraphicsView->setTransform(transform);
I'm not sure if this can help you, but I hope so.