I have been trying to display a gray-scale image using Qt. The image data is loaded from a .txt file that contains 256x256 float data. There is no header involved for the image. I have tried the solution posted in this link
I used QLabel class to call setPixmap of my uchar* image_data_array. Even though I could get a Qt GUI window to open, but the window shows just blank screen.
imageLabel -> setPixmap(QPixmap::fromImage(*myImage));
QImage img = AImage;
if (!AImage.isNull())
{
int pixels = img.width() * img.height();
if (pixels*(int)sizeof(QRgb) <= img.byteCount())
{
QRgb *data = (QRgb *)img.bits();
for (int i = 0; i < pixels; i++)
{
int val = qGray(data[i]);
data[i] = qRgba(val, val, val, qAlpha(data[i]));
}
}
}
return img;
Use RGBA for good grayscale.
How are you loading the QImage with the grey image data ?
QT doesn't have a greyscale image type, only a bilevel type. You can either create an RGB image with R=G=B=grey. Or more preferably use QImage::Format_Indexed8 and create a colour table where each entry has the same value as the index. i.e.
QImage *qi = new QImage(data_ptr, width, height, QImage::Format_Indexed8);
QVector<QRgb> my_table;
for(int i = 0; i < 256; i++) my_table.push_back(qRgb(i,i,i));
qi->setColorTable(my_table);
In QT 5.9.1 there is an option to create a grayscale image:
QImage *qi = new QImage(data_ptr, width, height, QImage::Format_Grayscale8);
Related
I'm implementing an image viewer on an embedded platform. The hardware is a sort of tablet and has a touch screen as input device. The Qt version I'm using is 5.4.3.
The QGraphicsView is used to display a QGraphicsScene which contains a QGraphicsPixmapItem. The QGraphicsPixmapItem containts the pixmap to display.
The relevant part of the code is the following:
void MyGraphicsView::pinchTriggered(QPinchGesture *gesture)
{
QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags();
if (changeFlags & QPinchGesture::ScaleFactorChanged) {
currentStepScaleFactor = gesture->totalScaleFactor();
}
if (gesture->state() == Qt::GestureFinished) {
scaleFactor *= currentStepScaleFactor;
currentStepScaleFactor = 1;
return;
}
// Compute the scale factor based on the current pinch level
qreal sxy = scaleFactor * currentStepScaleFactor;
// Get the pointer to the currently displayed picture
QList<QGraphicsItem *> listOfItems = items();
QGraphicsItem* item = listOfItems.at(0);
// Scale the picture
item.setScale(sxy);
// Adapt the scene to the scaled picture
setSceneRect(scene()->itemsBoundingRect());
}
As result of the pinch, the pixmap is scaled starting from the top-left corner of the view.
How to scale the pixmap respect to the center of the QPinchGesture?
From The Docs
The item is scaled around its transform origin point, which by default is (0, 0). You can select a different transformation origin by calling setTransformOriginPoint().
That function takes in a QPoint so you would need to find out your centre point first then set the origin point.
void QGraphicsItem::setTransformOriginPoint(const QPointF & origin)
i have raw image buffer. i am converting it into jpeg using following code:
height = 240;
width = 320;
raw_image=capture(width, height);//(c code uvc capture)
QImage tmpImage = QImage(raw_image, width, height, QImage::Format_RGB32 ); //image.format=RGB888
QByteArray im;
QBuffer bufferJpeg(&im);
bufferJpeg.open(QIODevice::WriteOnly);
tmpImage.save(&bufferJpeg, "JPG");
tmpImage.save("image1.jpg","JPG");
it is capturing and converting it into jpeg.but the captured image is not proper. i have attached the image for reference
and for QImage tmpImage = QImage(raw_image, width, height, QImage::Format_RGB16 ); image is
for QImage tmpImage = QImage(raw_image, width, height, QImage::Format_RGB444);
How can i get the proper image? thanks in advance.
wrong color space.
==> Format_RGB32
Try:
QVideoFrame::Format_YUYV or
QVideoFrame::Format_UYVY
I try to use QGraphicsView to display a map with some QGraphicItem-subclass showing region centers of the map. Conceptually, I organize the map as follow:
QGraphicsView
QGraphicsScene
QGraphicsPixmapItem : background image, fixed until next call of loadSetting
QGraphicsRectItem : legend, position relative to bg is fixed throughout app
QGraphicsEllipseItem : region centers
I want the map to behave as follow:
no scrollbars to be displayed, and the background image fillup all the visible area of the view/scene.
when the widget is re-sized, the QGraphics*Items will re-size themselves accordingly (as if the view is zoomed)
relative positions of QGraphicsEllipseItems, remain fixed until next call of loadSetting()
Now I have problem in getting the background image displayed properly.
Constructor [I'm adding this view to a QTabWidget directly: myTab->addTab("name", my_view_); ]
MyView::MyView(QWidget *parent) : QGraphicsView(parent) {
bg_pixmap_ = new QGraphicsPixmapItem();
legend_ = new MapLegend();
setScene(new QGraphicsScene(this));
scene()->addItem(bg_pixmap_);
scene()->addItem(legend_);
}
Load map setting (during program execution, this method may be invoked multiple times)
void MyView::loadSetting(Config* cfg) {
if (!cfg) return;
/* (a) */
scene()->clearFocus();
scene()->clearSelection();
for (int i = 0; i < symbols_.size(); i++)
scene()->removeItem(symbols_[i]);
qDeleteAll(symbols_);
symbols_.clear();
/* (a) */
/* (b) */
background_ = QPixmap(QString::fromStdString(cfg->district_map));
bg_pixmap_->setPixmap(background_);
for (size_t i = 0; i < cfg->centers.size(); i++) {
qreal x = cfg->centers[i].first * background_.width();
qreal y = cfg->centers[i].second * background_.height();
MapSymbol* item = new MapSymbol(x, y, 10);
symbols_.append(item);
scene()->addItem(item);
}
/* (b) */
update();
}
Questions
Now all items except the 'bg_pixmap_' got displayed, and I checked the 'background_' variable that it loads the image correctly. Is there anything I missed?
How do I implement the resizeEvent of MyView to cope with the desired 'resize-strategy'?
I have developed a small GUI in C++/Qt, I would like to know a fast way to test if image loaded is grayscale. In practise, when I load a grayscale image of gif format, I want it to be recognized as a grayscale image with depth()=8, and when I load a colored gif image, the depth of QImage would be 32.
Here's my open method :
void ImageViewer::open()
{
int status_off = 0;
fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::currentPath());
if (!fileName.isEmpty()) {
current_qimage = QImage(fileName);
if (current_qimage.isNull()) {
QMessageBox::information(this, tr("Image Viewer"),
tr("Cannot load %1.").arg(fileName));
return;
}
updateStatus(status_off);
// Image is colored with depth=8
if (current_qimage.depth()/8 != 4)
{rgblum_status = 0;}
else // Image is grayscale with depth=32
{rgblum_status = 1;}
loadImage();
}
}
From my first test, it seems that current_qimage, in current_qimage = QImage(fileName); inherits firstly from the format (gif here) before the contents of the image. Therefore, QImage has in two cases a depth() equal to 32.
How to make the difference between these two gif images (one grayscale and the other colored) ?
The QImage class has a function that you can call to test if the image is grayscale or not: QImage::isGrayscale(). It works for both 8-bit color table indexed images and 32-bit images.
I've a GtkToolBar which has say 3 GtkToolButtons with each of these having a stock icon value, and hence they all appear in the same size; now I added a 4th GtkToolButton with a custom image (.png), which was of an arbitrary dimension and only this button ended up looking huge (since the image was of higher resolution). What do I do to scale this GtkToolButton to match the other 3 buttons?
Here's the code which does what I briefed about:
GtkWidget *custom_icon = gtk_image_new_from_file(path);
GtkToolItem *toolbar_item = gtk_toggle_tool_button_new();
gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(toolbar_item), custom_icon);
gtk_tool_button_set_label(GTK_TOOL_BUTTON(toolbar_item), "Custom Item");
gtk_toolbar_insert(toolbar, toolbar_item, -1);
Here is another solution.
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(icon_file_path, NULL);
int width, height;
gdk_pixbuf_get_file_info (icon_file_path, &width, &height);
gtk_icon_theme_add_builtin_icon ("custom_icon", width, pixbuf);
g_object_unref (G_OBJECT (pixbuf));
GtkToolItem *toolbar_item = gtk_toggle_tool_button_new();
gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON(toolbar_item), "custom_icon");
If you have the image in different sizes, you can add them all and let Gtk choose the one of the correct size (or resize if not found): Just repeat the first five lines for each of the image files.
You can use your icon anywhere else and its size will also be adjusted automatically.
For example, to use it for your main window:
gtk_window_set_icon_name(GTK_WINDOW(main_window), "custom_icon");
Found it out myself! Here's the trick so that it helps someone like me. Query the icon size from the stock menu item, which is a enum (standard values like GTK_ICON_SIZE_BUTTON, GTK_ICON_SIZE_LARGE_TOOLBAR, etc.). Now get the pixel size using gtk_icon_size_lookup. Create a pixbuf from the custom icon/image file with the right dimensions. Create a GtkImage from that and set it to the new menu item and you're done!
GtkToolItem *stock_menu_item = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_NEW);
GtkIconSize toolbar_icon_size = gtk_tool_item_get_icon_size(stock_menu_item);
gint width = 0, height = 0;
gtk_icon_size_lookup(toolbar_icon_size, &width, &height);
GdkPixbuf *app_icon = gdk_pixbuf_new_from_file_at_size(icon_file_path, width, height, NULL);
GtkImage *tray_icon = gtk_image_new_from_pixbuf(app_icon);
g_object_unref(app_icon);
app_icon = NULL;
GtkToolItem *toolbar_item = gtk_toggle_tool_button_new();
gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(toolbar_item), tray_icon);