Here is my code :
void MainWindow::on_actionOpen_Image_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this,"Open Image File",QDir::currentPath());
if(!fileName.isEmpty())
{
QImage image(fileName);
if(image.isNull())
{
QMessageBox::information(this,"Image Viewer","Error Displaying image");
return;
}
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsPixmapItem item(QPixmap::fromImage(image));
scene.addItem(&item);
view.show();
}
}
I want to display image from file, code works fine but image disappiars very fast.
How can I pause image screen?
And how can I load image in "graphicsView" widget?
My code:
void MainWindow::on_actionOpen_Image_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this,"Open Image File",QDir::currentPath());
if(!fileName.isEmpty())
{
QImage image(fileName);
if(image.isNull())
{
QMessageBox::information(this,"Image Viewer","Error Displaying image");
return;
}
QGraphicsScene scene;
QGraphicsPixmapItem item(QPixmap::fromImage(image));
scene.addItem(&item);
ui->graphicsView->setScene(&scene);
ui->graphicsView->show();
}
}
It does not work.
How to fix this?
You need to create all your objects on the heap, otherwise they get deleted when they go out of scope:
QGraphicsScene* scene = new QGraphicsScene();
QGraphicsView* view = new QGraphicsView(scene);
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap::fromImage(image));
scene->addItem(item);
view->show();
Your second question might be related - scene is assigned to ui->graphicsView but it gets deleted immediately after, so again create all your objects on the heap.
If you don't have to stick with QGraphicsView one possibility is to use QLabel instead. I didn't manage to solve it for QGraphicsView...
QString filename = "X:/my_image";
QImage image(filename);
ui->label->setPixmap(QPixmap::fromImage(image));
Related
I am dynamically creating a QLabel named label (that has a QPixmap) inside a QHBLayout named layout inside a parent QWidget named by this such that the QLabel image resizes with parent this but maintains the original image aspect ratio.
What I am doing now is the following:
QHBoxLayout* layout = new QHBoxLayout(this);
label = new QLabel(str, this); /* This Label is my concern */
label->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
layout->addWidget(label);
layout->setAlignment(Qt::AlignCenter);
this->setLayout(layout);
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(0);
label->setScaledContents(true);
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
After searching online and as suggested in the accepted answer in Qt layouts - Keep widget aspect ratio while resizing, I even tried creating my own MyLabel class and defining sizeHint() and resizeEvent(QResizeEvent* event) as follows:
QSize MyLabel::sizeHint() const
{
QSize s = size();
lastHeight = s.height();
lastWidth = s.width();
QSize qs = QLabel::sizeHint();
float ratio = std::min(((float)qs.width())/lastWidth, ((float)qs.height())/lastHeight);
s.setWidth(lastWidth*ratio);
s.setHeight(lastHeight*ratio);
return s;
}
void MyLabel::resizeEvent(QResizeEvent* event)
{
QLabel::resizeEvent(event);
if(lastHeight!=height())
{
updateGeometry();
}
}
But the label image still resizes without maintaining aspect ratio.
What am I missing here?
Any help will be highly appreciated.
Thanks in advance.
Try using the subclass of QLabel listed here:
https://stackoverflow.com/a/22618496/999943
Hope that helps.
Try to resize your image instead of QLabel. E.g. by hangling parent widget's resizeEvent and doing something like:
const QPixmap* pixmap = label->pixmap();
if (pixmap->width() >= newGeometry.width())
{
QPixmap scaledPixmap = pixmap->scaledToWidth(newWidth, Qt::SmoothTransformation);
label->setPixmap(scaledPixmap);
}
I am working on Xamarin form in which header title will have weather temperature and weather icon on its right side.
For example
New York 60' F SunnyIcon
I am using openweather api to fetch the data.
Problem is, I am not able to create a dynamic image holder on the Xamarin Form Header.
How to have a dynamic image on the Xamarin Form Header?
Attached is a sample app which i am working on based on source code which i downloaded from github ...
I'm not sure what you mean by "Header," but if you're trying to add an icon to the Navigation Bar, you can do that by calling ToolbarItems.add() in the constructor of your page like this:
public myPage()
{
InitializeComponent();
ToolbarItems.Add(new ToolbarItem("Weather", "WeatherIcon.png", async () =>
{
//Code to Execute when Icon is tapped
}));
}
When adding the ToolbarItem, the first parameter is the name of the item, the second is the name of the image that will be displayed at the end of the Navigation bar, and the last one is optional which creates a method that is executed when the icon is tapped.
If you need the icon to be different depending on the current weather, you can do that like this:
public myPage()
{
InitializeComponent();
string weatherIconString = "";
if(weather.isSunny) // Edit contition however you need
weatherIconString = "SunnyIcon.png";
else
weatherIconString = "CloudyIcon.png";
ToolbarItems.Add(new ToolbarItem("Weather", weatherIconString));
}
You have to write a custom renderer like this: and the result:
public class CustomNavigationPageRenderer : NavigationRenderer
{
public override void ViewDidLoad()
{
//I'm getting width and height so i can rescale the image
nfloat navigationBarWidth = NavigationBar.Frame.Width;
nfloat navigationBarHeight = NavigationBar.Frame.Height;
//you can load image from your bundle,so you can add your weather icons on bundle -> under Resources folder
var img = UIImage.FromBundle("navigationbarbackground.jpg");
//create image context to draw image
UIGraphics.BeginImageContextWithOptions(new CGSize(navigationBarWidth, navigationBarHeight), true, 0);
//I'm filling the background with a color so it is the same as with my background image color
UIColor.FromRGB(54, 60, 65).SetFill();
UIGraphics.RectFill(new CGRect(0, 0, navigationBarWidth, navigationBarHeight));
//draw your image according to the coordinates of the navigation bar, i put it to the right top with a small right padding,
//you have to play with coordinates according to your needs
img.Draw(new CGRect(navigationBarWidth - navigationBarHeight - 30,//move 30px to the left (do not paste to right border :))
0, navigationBarHeight, navigationBarHeight));
UIImage backgroundImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
NavigationBar.SetBackgroundImage(backgroundImage, UIBarMetrics.Default);
//bonus :) change your title color
UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes()
{
TextColor = UIColor.White,
});
base.ViewDidLoad();
}
}
No matter what i try i cant get my text to load into a texture in SDL 2.0 using SDL_ttf.
Here is my textToTexture code
void sdlapp::textToTexture(string text, SDL_Color textColor,SDL_Texture* textTexture)
{
//free prevoius texture in textTexture if texture exists
if (textTexture != nullptr || NULL)
{
SDL_DestroyTexture(textTexture);
}
SDL_Surface* textSurface = TTF_RenderText_Solid(m_font, text.c_str(), textColor);
textTexture = SDL_CreateTextureFromSurface(m_renderer, textSurface);
//free surface
SDL_FreeSurface(textSurface);
}
And then here is me loading the texture and text
bool sdlapp::loadMedia()
{
bool success = true;
//load media here
//load font
m_font = TTF_OpenFont("Fonts/MotorwerkOblique.ttf", 28);
//load text
SDL_Color textColor = { 0x255, 0x255, 0x235 };
textToTexture("im a texture thing", textColor, m_font_texture);
return success;
}
And then this is the code i am using to render it
void sdlapp::render()
{
//clear the screen
SDL_RenderClear(m_renderer);
//do render stuff here
SDL_Rect rect= { 32, 64, 128, 32 };
SDL_RenderCopy(m_renderer, m_font_texture, NULL, NULL);
//update the screen to the current render
SDL_RenderPresent(m_renderer);
}
Does anyone know what i am doing wrong?
Thanks in Advance, JustinWeq.
textToTexture renders the text with SDL_ttf, the resulting SDL_Texture address is then assigned to a variable called textTexture. Problem is, textTexture is a local variable pointing to the same address as m_font_texture. They're not the same variable, they're different variables poiting to the same place, thus you're not changing any callee variables.
For clarification on pointers, I'd recommend seeing question 4.8 of the C-FAQ
I'd make textToTexture return the new texture address, and don't bother freeing resources that are not managed by it (m_font_texture belongs to sdlapp, it should be managed by it).
I would like to create a layout with a fullscreen background image and some UI elements on top of it. The twist is this:
I would like the background image to swipeable like a carousel, but I would like the UI elements to stay in place. That is if I swipe the screen, the background image should slide to the side and a new image should replace it. I know about CarouselPage, but it seems to me that it won't do the trick, since a Page can have only one child which it replaces on swipe, meaning that the UI elements would be descendants of the CarouselPage and therefore would also be animated.
I am guessing I need some sort of custom renderer here, but how should I go about designing it? Should it be one fullscreen Image control replaced be another fullscreen Image control with the UI elements on top of it? And how can I do this? Or is there an all together better approach?
I am developing for iOS and Android using Xamarin.Forms.
Thanks in advance.
I don't like repeating myself much, and I think that multiple layers of actionable items can lead to confusion, but the problems appeals to me and I can see a niche for this kind of UI, so here's my take on your question.
Let's assume this is the (Xamarin.Forms.)Page you want to render with a custom carousel background:
public class FunkyPage : ContentPage
{
public IList<string> ImagePaths { get; set; }
public FunkyPage ()
{
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center,
Spacing = 12,
Children = {
new Label { Text = "Foo" },
new Label { Text = "Bar" },
new Label { Text = "Baz" },
new Label { Text = "Qux" },
}
};
ImagePaths = new List<string> { "red.png", "green.png", "blue.png", "orange.png" };
}
}
The renderer for iOS could look like this:
[assembly: ExportRenderer (typeof (FunkyPage), typeof (FunkyPageRenderer))]
public class FunkyPageRenderer : PageRenderer
{
UIScrollView bgCarousel = new UIScrollView (RectangleF.Empty) {
PagingEnabled = true,
ScrollEnabled=true
};
List<UIImageView> uiimages = new List<UIImageView> ();
protected override void OnElementChanged (VisualElementChangedEventArgs e)
{
foreach (var sub in uiimages)
sub.RemoveFromSuperview ();
uiimages.Clear ();
if (e.NewElement != null) {
var page = e.NewElement as FunkyPage;
foreach (var image in page.ImagePaths) {
var uiimage = new UIImageView (new UIImage (image));
bgCarousel.Add (uiimage);
uiimages.Add (uiimage);
}
}
base.OnElementChanged (e);
}
public override void ViewDidLoad ()
{
Add (bgCarousel);
base.ViewDidLoad ();
}
public override void ViewWillLayoutSubviews ()
{
base.ViewWillLayoutSubviews ();
bgCarousel.Frame = View.Frame;
var origin = 0f;
foreach (var image in uiimages) {
image.Frame = new RectangleF (origin, 0, View.Frame.Width, View.Frame.Height);
origin += View.Frame.Width;
}
bgCarousel.ContentSize = new SizeF (origin, View.Frame.Height);
}
}
This was tested and works. Adding a UIPageControl (the dots) is easy on top of this. Autoscrolling of the background is trivial too.
The process is similar on Android, the overrides are a bit different.
this is a post I have made on the adobe forum...
I'm newish to flash and i'm doing a presentation as part of a University assignment.
My problem is basically this. As part of my presentation I have a photo gallery which uses thumbnail images as buttons and then a UI loader to load a pop up version of the larger image from my webserver - as per https://www.youtube.com/watch?v=Peo_nT9HHa0
The image was created on photoshop. It is a .jpg and has text within the image that describes underneath it what the image is all about. The text within photoshop is set to anti-aliasing 'smooth' and when I test the movie within flash, the text underneath the image looks fine - just as it does in photoshop.
However, when I publish and upload the .swf file to my webserver and view the image through a browser, the text looks awful - all jaggy and broken if that makes sense.
Any ideas why?
I was given a reply of...
If you are loading the images dynamically then you will have to set the smoothing property true after the file(s) has been loaded. So if you don't currently have a listener for the images finishing loading, you will need one, and an event handler function to assign the smoothing property to true for each of them.
Can anyone help with creating the actionscript for this listener and event handler function?
I basically have a gallery movie clip with buttons that act as clickable thumbnails. The actionscript for that is...
btnImage1.addEventListener(MouseEvent.CLICK, loadimage1);
function loadimage1 (event:MouseEvent):void{
imagetxt.text = "a";
togglewindow.gotoAndPlay(2)
}
and then a UI loader that displays the larger image when a thumbnail is clicked
if (MovieClip(this.parent).imagetxt.text == "a"){
var imgurl:String ="IMAGE URL";
var myrequest:URLRequest = new URLRequest(imgurl);
myloader.load(myrequest);
}
As indicated, you should always turn smoothing on if the image is going to be scaled at all. It uses a different scaling algorithm that blurs pixels rather than deletes them. Take note that it is substantially slower to smooth, but on modern machines you shouldn't notice the difference unless you are doing it to thousands of images all at once.
After instantiation, add a Event.COMPLETE handler to Loader.contentLoaderInfo.
var myLoader = new Loader();
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteHandler);
Then in the handler, you can access the Bitmap and turn smoothing on.
function loaderCompleteHandler(e:Event):void {
var image:Bitmap = myLoader.content as Bitmap; //Loader.content is typed as a DisplayObject, so we need to cast it as a Bitmap
image.smoothing = true;
}
And that should solve the issue. You may need to add the image object to the stage rather than the myLoader object. I don't think you'll have to, but I can't remember.
Just add event an event listener to your loader. Like this:
load.addEventListener(Event.COMPLETE,doneLoad);
then in the doneLoad function get the event.data and cast it to Bitmap and set the bitmap smoothing to true:
var myBitmap:Bitmap= e.target.data as Bitmap;
myBitmap.smoothing=true;
//add bitmap to parent ....
I wrote you universal method for loading images, you should pass 3 arguments to the method: holder for big images, image path, and rectangle to restrict image bounds and resize them. This method should be sufficient for your task.
private function loadImage(holder:DisplayObjectContainer, path:String, bounds:Rectangle):void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function (e:Event):void {
var bitmap:Bitmap = loader.content as Bitmap;
if (bitmap != null) {
bitmap.smoothing = true;
//Resize bitmap to fit bounds
var availableRatio:Number = bounds.width / bounds.height;
var componentRatio:Number = bitmap.width / bitmap.height;
if (componentRatio > availableRatio) {
bitmap.width = bounds.width;
bitmap.height = bounds.width / componentRatio;
} else {
bitmap.width = bounds.height * componentRatio;
bitmap.height = bounds.height;
}
//Clear previous
var i:uint, len: uint = holder.numChildren, old: Bitmap;
for(i; i < len; ++i){
old = holder.removeChildAt(0) as Bitmap;
old.bitmapData.dispose();
}
//Here you can add some appear animation
bitmap.x = bounds.x + ((bounds.width - bitmap.width) >> 1);
bitmap.y = bounds.y + ((bounds.height - bitmap.height) >> 1);
holder.addChild(bitmap);
}
});
loader.load(new URLRequest(path));
}
Usage:
loadImage(myContainer, "Path-to-Image", new Rectangle(20, 20, 400, 200));