Image gets clipped while changing orientation using Qt - image

HI all,
I wnt to develop an ImageViewer using qt. I m trying to resize big images by scaling them. My problem is , when i change the screen orientation some part of the image gets clipped and also if i open the image in landscape mode, by default the size of image remains small even when i change back to portrait mode. What am i Doin wrong?
Please help me out. Heres the code dat i hv written
ImageViewer::ImageViewer()
{
setAttribute(Qt::WA_DeleteOnClose);
QAction *back = new QAction(this);
back->setText(QString("Back"));
connect(back,SIGNAL(triggered()),this,SLOT(close()));
back->setSoftKeyRole(QAction::PositiveSoftKey);
addAction(back);
imageLabel = new QLabel();
imageLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
imageLabel->setAlignment(/*Qt::AlignLeft|*/Qt::AlignCenter);
QWidget *widget = new QWidget;
layout=new QStackedLayout();
layout->addWidget(imageLabel);
widget->setLayout(layout);
setCentralWidget(widget);
}
void ImageViewer::showImage(QString filePath)
{
QImageReader reader;
reader.setFileName(filePath);
QSize imageSize = reader.size();
imageSize.scale(size(), Qt::KeepAspectRatio);
reader.setScaledSize(imageSize);
QImage image = reader.read();
imageLabel->setPixmap(QPixmap::fromImage(image));
imageLabel->adjustSize();
}

You should re-implement QLabel's resizeEvent or install event filter to it and handle QResizeEvent there
The content of showImage method should go to handler of a resize event.
Currently you are using size() of ImageViewer widget (which seems to be derived from QMainWindow), it's better to use imageLabel.size(); or the best QResizeEvent::size() as this will prevent a problem if you will change UI layout in future.

Related

Unity 3D: Changing sprite animation using UI button

I'm following this tutorial on youtube about changing sprite animation in code, and I was wondering if I could change this to changing sprite animation using UI button. does anyone knows how to do this. Thank you!
EDIT:
The script that I reposed kind of works thanks to your help, it changes the sprite image from image one to image two but what I'm basically trying to achieve is that each time that I click the UI button the sprite image will change from sprite image one (UI button click)> sprite image two (UI button click)> sprite image three (UI button click)> then repeat the process instead of the sprite image automatically changing itself.
Buttons have an OnClick event http://docs.unity3d.com/ScriptReference/UI.Button-onClick.html
You just create a method that gets called when the button is clicked, in your case the changing sprite code. Seen as you are using a timer though you will need to use something like a bool because onClick() only gets called once when clicked, not every frame.
Look https://www.youtube.com/watch?v=J5ZNuM6K27E
bool b_RunSpriteAnim;
public void onClick(){
b_RunSpriteAnim = true;
}
void Update(){
if (b_RunSpriteAnim)
//your anim sprite stuff
}
Then once the sprite anim has finished, just toggle b_RunSpriteAnim to false and reset the timer.
Edited:
You don't need a boolean. I only thought you wanted it because you were using a timer (as based on the Youtube link). If you just want to change the sprite immediately then you do not need it. As for Imagethree not working, it's because you have never included it in your code. It isn't clear what you are trying to achieve with Imagethree, if you included this in onClick as well it would just overwrite the image two that was just set, so I am not sure what you are looking to achieve.
public void onClick(){
this.gameObject.GetComponent<SpriteRenderer>().sprite = Imagetwo;
}
Second Edit:
public Sprite[] Images;
//Index starts at one because we are setting the first sprite in Start() method
private int _Index = 1;
void Start(){
//Set the image to the first one
this.gameObject.GetComponent<SpriteRenderer>().sprite = Images[0];
}
public void onClick(){
//Reset back to 0 so it can loop again if the last sprite has been shown
if (_Index >= Images.Length)
_Index = 0;
//Set the image to array at element index, then increment
this.gameObject.GetComponent<SpriteRenderer>().sprite = Images[_Index++];
}

Libgdx FreeTypeFont: font generated dynamically doesn't scale in Label

I'm trying to figure out how to realize the HUD interface for my brand new game.
I wanted to create it by using the scene2d.ui set of widgets because I've heard that it's more suitable for a responsive UI.
So, I'm trying to create a simple HUD in which there's a score Label aligned at the top-right side of the screen and a pause Button placed on the top-left side of the screen.
Now... I'm using a root Table (as explained in the Table guide https://github.com/libgdx/libgdx/wiki/Table#quickstart) that fills the stage.
I wanted to create a custom class for handling all the hud interface such as:
public class Hud extends Table{
private Label scoreLabel;
private Button pauseButton;
public Hud(){
setFillParent(true);
BitmapFont font = (BitmapFont) MyGame.assetManager.get(Constants.COUNTERS_FONT_NAME);
LabelStyle labelStyle = new LabelStyle(font,Color.WHITE);
scoreLabel = new Label("score:0", labelStyle);
add(scoreLabel).width(2).height(1);
}
}
The issue I'm fighting with is the following: the text inside the Label does not stay inside the Label.
I mean: activating the debug mode I can see the rectangle representing the Label with the correct dimensions...but the text is completely out of bounds and does not scale.
As you can see the font I use is a BitmapFont that is generated when the Game starts via the library FreeTypeFont...The font is then added to the AssetsManager of the game.
I post the code I use for adding the font generator to the assets manager:
//Register the FreeTypeFontGeneratorLoader
InternalFileHandleResolver resolver = new InternalFileHandleResolver();
assetManager.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
assetManager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));
//Load fonts
FreeTypeFontLoaderParameter countersFontParameters = new FreeTypeFontLoaderParameter();
countersFontParameters.fontFileName = Constants.BASE_FONT_NAME;
countersFontParameters.fontParameters.size = 45;
countersFontParameters.fontParameters.borderColor = Color.BLACK;
countersFontParameters.fontParameters.borderWidth = 1;
assetManager.load(Constants.COUNTERS_FONT_NAME, BitmapFont.class, countersFontParameters);
As you can see I load just one BitmapFont with a size of 45 pixels.
I don't know what the problem is; I would like to try with a classic BitmapFont .fnt in order to see if the problem is in the way the BitmapFont is generated but I'd also like to keep the FreeTypeFont solution.
Thanks in advance,
Luca
P.S.
One thing about the Stage... it uses a ScalingViewport so the dimensions are not in pixels but in virtual units (because my Game uses Box2d and I need a common unit both for the rendering and the physic simulation).
I'm pretty sure that Label will not respond on automatic scaling of the viewport until you will call label.setFontScale( theScale ) explicite.
The best idea here, in my opinion, will be to create another stage exclusively for a HUD so you will have your stage with ScalingViewport (I admit I've never used this one - isn't it better to use some Fill or aomething like this one?) and another stage with FitViewport above for example.
I find it very reasonable and intuitive since it will be like having your HUD displayed on yours car windscreen when driving the car.
The code should looks like:
//in your show method
viewport = createYourScalingViewport();
stage = new Stage();
stage.setViewport(viewport);
HUDviewport = new FitViewport(screenWidth, screenHeight);
HUDstage = new Stage();
HUDstage.setViewport(HUDviewport);
...
//adding some actor to stages
stage.addActor(actor1);
stage.addActor(actor2);
//BUT
HUDstage.addActor( yourHudInstance );
...
//then in your render method act() and draw() stage then HUDstage so the HUD will be above stage
stage.act();
stage.draw();
HUDstage.act();
HUDstage.draw();
Remember of updateing HUDviewport in case of window resizing in the resize Screen method
I guess I've solved my problem.
It seems to be that it doesn't make sense to set the label dimensions.
If anyone needs to have a container that was tight to the text is rendered inside the label the best solution is to create a custom class like this below that extends an HorizonaltGroup (o VerticalGroup).
Let's imagine I need a score label for my game:
public class ScoreLabel extends HorizontalGroup{
...
}
Inside this class I create a Label property and I add it as an Actor.
public class ScoreLabel extends HorizontalGroup{
private Label scores;
public static final float FONT_SCALE = 0.9f;
public ScoreLabel(){
BitmapFont font = MyGame.assetManager.get(Constants.COUNTERS_FONT_NAME);
LabelStyle labelStyle = new LabelStyle(font, Color.WHITE);
scores = new Label(getScoreText(), labelStyle);
scores.setAlignment(Align.left);
scores.setFontScale(FONT_SCALE);
addActor(scores);
}
}
If you activate the debug mode you'll notice that there's a container that is perfectly tight to the text is rendered.
The code above simply loads a BitmapFont previously loaded inside the game assets manager.
Then a font scale is applied...I guess it could be added inside a skin property
Anyway...This is the best solution for me.
I'm still using a stage with a ScalingViewport, in this way I have not to use pixels as unit and all the dimensions are scaled to fill the device screen.
Bye,
Luca

I want to show a picture in QWidget, but it doesn't work

My code is:but I can't find image in QWidget. What can I do if i want to show the image ? And what's wrong with my code?
QTtest::QTtest(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout * m_viewLayout = new QHBoxLayout();
this->setLayout(m_viewLayout);
QHBoxLayout * showLayout = new QHBoxLayout();
QHBoxLayout * btnLayout = new QHBoxLayout();
m_viewLayout->addLayout(showLayout);
m_viewLayout->addLayout(btnLayout);
widget1 = new QWidget();
showLayout->addWidget(widget1);
QPixmap image("C:\\Users\\zhq\\Desktop\\1.png");
QPainter painter(widget1);
painter.drawPixmap(QPoint(0,0),image);
widget2 = new QWidget();
showLayout->addWidget(widget2);
QPushButton * btn = new QPushButton("btn");
btnLayout->addWidget(btn);
showLayout->addStretch();
}
There's a couple of thing wrong with your code.
Assuming that the image is loaded correctly, you should paint the image in the void QWidget::paintEvent(QPaintEvent * event) of your widget. Do not paint outside of paint events. Also, as you're currently doing it, the image will be overwritten the next time the widget updates/reapints itself anyway.
You might consider going an easier route and use a QLabel in your layout instead of widget1. You can then call QPixmap::fromImage() to convert the image to a pixmap and QLabel::setPixmap() on the label to display your image.

How to fit image to center while using TouchImageView?

I have a gallery application that needs to zoom and pan. Instead of using default imageview , I found a sample touchmageview on internet and copied it. I called my images with TouchImageView and now i can zoom and pan the images that I called from my drawable folder. Then I added gallery to my project. Now the problem is that I can not fit the images to the screen.When I use scaletype.center then it fits the image to the screen but now zoom and pan features are not working. This is my gallerylistener ;
gallery.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Toast.makeText(Display.this, "Your selected position = " + position, Toast.LENGTH_SHORT).show();
// show the selected Image
img.setScaleType(ScaleType.CENTER_INSIDE);
img.setImageResource(Imgid[position]);
}
});
As you see , if I add img.setScaleType(ScaleType.CENTER_INSIDE); then the TouchImageView class doesn't work and I am not able to zoom and pinch and pan etc.. It only display the image. When I delete this code , then I can zoom but then when I change the picture to another one , the new one has the previous image's size. But I want to fit them to the center. Is there any way to reset the scaletype before calling the new image ?
By the way I have only one imageview in xml.
There is a similar question on this link but the solution did not work for me.
how to get setScaleType(ImageView.ScaleType.FIT_CENTER) effect using setScaleType(ImageView.ScaleType.MATRIX)

WP7 transition between Canvas's in a Grid

I have two canvas's in a Grid, full scene "images" that I want to transition, I wonder how I would go about transitioning between these two Canvas controls.
Programatically I add the first canvas to the grid, then I add the second canvas to the grid, and remove the first, what I really want to do is transition between them.
Any suggestions on how I might achieve this programatically?
Thanks.
Edit: I have implemented this method, but am having problems, anyone able to tell me if I'm using it wrong?
private void doTransitionIn(Canvas slide)
{
SlideTransition slideLeft = new SlideTransition();
slideLeft.Mode = SlideTransitionMode.SlideDownFadeIn;
ITransition transition = slideLeft.GetTransition(slide);
transition.Completed += delegate { transition.Stop(); }; transition.Begin();
}
private void doTransitionOut(Canvas slide)
{
SlideTransition slideLeft = new SlideTransition();
slideLeft.Mode = SlideTransitionMode.SlideDownFadeOut;
ITransition transition = slideLeft.GetTransition(slide);
transition.Completed += delegate { transition.Stop(); }; transition.Begin();
}
And here is how I use it:
SceneGrid.Children.Add(nextCanvas);
doTransitionIn(nextCanvas);
doTransitionOut(currentCanvas);
SceneGrid.Children.Remove(currentCanvas);
The problem with this is that the animation only seems to start from part way down the screen, as in, i only see it slide the last 20 or so pixels, it doesn't slide all the way.
Depending on what you mean by "transition" I'd look at creating a StoryBoard to animate the hiding/showing of each canvas.
I would recommend using the TransitioningContentControl which is part of the Silverlight Toolkit. To use this control, make your first Canvas the Content of this control. To transition, simply change the Content to your next Canvas and the TransitioningContentControl does the rest!
There are a number of blog posts that provide tutorials for this control:
http://blogs.academicclub.org/uidev/2010/06/12/transitioning-content-in-silverlight/

Resources