I'm using QImage class from Qt to display the picture on screen. For some reason I need to display even not fully loaded images (e.g. when some data blocks are absent).
I would like to see something like this in result:
Standard image viewer for Windows can show me such broken images, but I can’t achieve same behavior with QImage. Image not displayed at all if broken. Is there a way to display a partially loaded image by QImage? Maybe I should use other Qt-related classes for that purpose?
QImage is probably too high level for this. If you do not want to go at the level of individual libraries for each format (e.g. libpng), you should consider using CImg. It is a small header only c++ library to read and process images, which use the low level libraries available to read images. From a loaded CImg you should be able to get the data into a QPixmap or QImage to display it.
I am porting an video streamer application to QT (from HTML), I just had the webcam working using QT, and now I want to know How can I get the RGB Video buffer from a QT Camera? All the samples I can see is capturing image to a file.
I am using QT Widgets and not QML since its a desktop application.
What I am trying to do is to get the buffer image of the camera, compress it and send to network.
And I want to trigger this manualy since I want to call the capture of next frame when all the compression and sending is done to prevent timing issue.
i'm using qt creator to create sample Remote Assistance
my project have 2 part server and client
the client taking screenshot and send it to server but screenshot pictures have to much quality and it take too much size and is not good idea to send it from local area network or internet protocol
i need to resize image size or convert it to low quality so that can be almost Recognizable
this is my screenshot codes
void MainWindow::shootScreen()
{
originalPixmap = QPixmap(); // clear image for low memory situations
// on embedded devices.
originalPixmap = QGuiApplication::primaryScreen()->grabWindow(0);
//emit getScreen(originalPixmap);
updateScreenshotLabel();
}
void MainWindow::updateScreenshotLabel()
{
this->ui->label_2->setPixmap(originalPixmap.scaled(this->ui->label_2- >size(),
Qt::KeepAspectRatio,
Qt::SmoothTransformation));
}
Looks like you know how to change an image size, why isn't that enough?
Just do:
QPixmap smallPixmap = originalPixmap.scaled( QSize( originalPixmap.size().x()/4, originalPixmap.size().y()/4 ), Qt::KeepAspectRatio, Qt::SmoothTransformation );
And send smallPixmap instead of originalPixmap.
You could (should) also compress the image using QImageWriter, this will allow you to create an image compressed with jpeg format, which should also reduce the memory usage.
Check this, looks like they do what you are trying to do.
I saw Fennex attempt to access the camera api of Android within Cocos2dx. But on the project listed, I am not sure how I am going to access the camera and the photogallery. Is there a way to do this in Cocos2dx just as you do with Cocos2d?
Thank you!
This Post says there is no cocos2d-x class to do that but provided this code segments:
The gist of it is, on Android :
- call Java code to start an Intent
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
instance.startActivityForResult(cameraIntent, 31); //31 is an ID to recognize that intent yourself
get the Bitmap returned by the Intent
Bitmap original = (Bitmap) intent.getExtras().get("data");
eventually, scale it for your own needs (especially on lower-end device if you also get images from the library)
save it in the file format you want (I use png)
FileOutputStream stream = new FileOutputStream(path);
/* Write bitmap to file using JPEG or PNG and 80% quality hint for JPEG. */
bitmap.compress(CompressFormat.PNG, 80, stream);
bitmap.recycle(); //ensure the image is freed;
stream.close();
If you want the same for iOS look at this post
I am creating an app in Qt, similar to scribble (given in sample app). Purpose is to let user draw freehand and once finished, upload these drawing to net. As of now I am saving the drawing as PNG image every 5 seconds, so that the loss of data in an event of unexpected shut-down is minimum (I kept 5 sec to minimize write operations; Real real-time would be highly desirable).
But the problem is, I am saving the entire page as an image every 5 seconds, where the new data added may be few pixels. I was wondering if I could write ONLY the new pixels added into the disk; there is no constraint that I should use PNG while saving; I can convert the data to PNG at the end when user says he is finished.
The piece of code for saving very basic;
void SaveData(const QString &fileName, const char *fileFormat, QImage image)
{
mutex.lock();
QImage visibleImage = image;
if (visibleImage.save(fileName, fileFormat, 50))
{
system("sync");
mutex.unlock();
return true;
} else {
mutex.unlock();
return false;
}
}
I just wonder if REAL real-time save as the pixels getting added if possible..!
Thanks in advance
DK
I suggest you to use tiles to save the image. Split the canvas to many e.g. 64x64 rectangles. And save each rectangle into separate file. When something is changed, you need to rewrite only few small files instead of rewriting the whole picture.
Also there is another dangerous thing in your code. When you run QImage::save, it most likely will erase file contents and write new contents. If the system was shutted down between there two actions, your file will became empty. So it's important to write new contents to a temporary file and then move it to the proper location. Keeping several old version of a file also can be useful. Who knows how the file system will react on the shutdown.
You could maybe use a memory mapped file, something like:
QFile file("rawimage.dat");
file.open(QIODevice::ReadWrite);
// Make sure there is enough memory for the image
quint32 width = 16;
quint32 height = 16;
quint32 bpp32 = 4;
qint64 file_size = width * height * bpp32;
file.resize(file_size);
uchar* mem = file.map(0, file_size);
// make a QImage that uses the file as memory
QImage img(mem, 16, 16, QImage::Format_ARGB32);
// Do some drawing in the image
img.fill(0);
// finished with the file
file.unmap(mem);
file.close();
You will need to check that it actually flushes to disk correctly - I haven't tested this. Ideally on Windows you'd want to be able to call 'FlushViewOfFile' on the memory mapped handle to ensure that modified pages are written to disk. It doesn't look like there is a way of calling this in Qt so you might need to do something operating system specific here to ensure that the disk image is consistent when you want it to be.
You could create a list of QPainterPath objects of the drawn items, which are then rendered to the QImage. You'd need to change the mouse events to do the following: -
Mouse Down : create a new QPainterPath (painterPath) and call painterPath->moveTo
Mouse Move : call painterPath->LineTo
Mouse Up : Store the QPainterPath in a list.
In the paint event, you then pass each new QPainterPath to be drawn
To back up, every n seconds, open up a file and append a stream of the new QPainterPaths since the last time the list was saved.
To restore, open the file, stream them back in and draw them on to the Image.
This can be optimised to check for new items and not to bother saving if none exist. In addition, rather than being time based, you could maintain a number of points that are created in the QPainterPath and only save when it exceeds a certain number.
Note that if you do go down this route, you may also want to store Painter settings with each QPainterPath, if the user can also change things such as pen colour, width etc.
Other advantages come with using QPainterpath - for example, the user could open up one image and then a second, choosing to have it drawn on top of the first.
If you want real-time saving then I suggest you use an uncompressed bitmap format. Changing pixels would be as simple as seeking inside the file to the x-y co-ordinates, usually calculated as
file.seek(y * lineWidth + x * pixelDataSize);
file.write(pixelData);