Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
SumiSadiq
Posts: 148
Registered: ‎04-08-2013
My Device: Blackberry 10
My Carrier: Blackberry
Accepted Solution

save the downloaded images

I want to download an image from the server.After that I have to save that image to assets folder.

 

I managed to download the image from the server by referring this example:: https://github.com/RileyGB/BlackBerry10-Samples/tree/master/WebImageViewSample

 

Now my problem is:

I want to save that image to assets folder

 

From the above example as the reply of the QNetworkRequest I got the Images.Now instead of showing the image directly I want to save them to assets folder.How can I do that.Plz help me out

 

Below is the code where I try to access the image from server

#include "WebImageView.h"
#include <QNetworkReply>
#include <QNetworkDiskCache>
#include <QDesktopServices>
#include <bb/cascades/Image>

using namespace bb::cascades;

QNetworkAccessManager * WebImageView::mNetManager = new QNetworkAccessManager();
QNetworkDiskCache * WebImageView::mNetworkDiskCache = new QNetworkDiskCache();

WebImageView::WebImageView() {

	// Initialize network cache
	mNetworkDiskCache->setCacheDirectory(QDesktopServices::storageLocation(QDesktopServices::CacheLocation));

	// Set cache in manager
	mNetManager->setCache(mNetworkDiskCache);

}

const QUrl& WebImageView::url() const {
	return mUrl;
}

void WebImageView::setUrl(const QUrl& url) {

	// Variables
	mUrl = url;
	mLoading = 0;

	// Reset the image
	resetImage();

	// Create request
	QNetworkRequest request;
	request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
	request.setUrl(url);

	// Create reply
	QNetworkReply * reply = mNetManager->get(request);
	QObject::connect(reply,SIGNAL(finished()), this, SLOT(imageLoaded()));
	QObject::connect(reply,SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(dowloadProgressed(qint64,qint64)));

	//
	// Note:
	// If you see Function "downloadProgress ( qint64 , qint64  ) is not defined"
	// Simply close this file, delete the error and compile the project
	//

	//emit urlChanged();
}

double WebImageView::loading() const {
	return mLoading;
}

void WebImageView::imageLoaded() {

	// Get reply
	QNetworkReply * reply = qobject_cast<QNetworkReply*>(sender());
	//here Iam getting the images as the reply.Now instead of loading them directly I want to save this image

	// Process reply
	QByteArray imageData = reply->readAll();

	// Set image from data
	setImage( Image(imageData) );

	// Memory management
	reply->deleteLater();

}

void WebImageView::dowloadProgressed(qint64 bytes,qint64 total) {

	mLoading =  double(bytes)/double(total);
	emit loadingChanged();

}

 

Please use plain text.
Developer
DrShavargo
Posts: 133
Registered: ‎05-10-2013
My Device: Blackberry Z10
My Carrier: -

Re: save the downloaded images

After you process the reply,

 

// Process reply
QByteArray imageData = reply->readAll();

add these lines after your code to save to image:

 

QImage image = QImage::fromData(iamgeData, "BMP");
QFile outFile("shared/photos/temp1.bmp"); //change to your file path
outFile.open(QIODevice::WriteOnly);
image.save(&outFile, "JPEG");

 

Don't forget to remove your setImage call.

----------------------------------------
Remember to mark the thread as solved at the post that solved your problem, and if you like a post, like it!
Please use plain text.
Developer
SumiSadiq
Posts: 148
Registered: ‎04-08-2013
My Device: Blackberry 10
My Carrier: Blackberry

Re: save the downloaded images

Thanks for your answer.I tried this as below

void WebImageView::imageLoaded() {

	// Get reply
	QNetworkReply * reply = qobject_cast<QNetworkReply*>(sender());
	//saveImage(reply);

	// Process reply
	QByteArray imageData = reply->readAll();
	QImage image = QImage::fromData(imageData, "BMP");
	QFile outFile("images/temp1.bmp"); //change to your file path
	outFile.open(QIODevice::WriteOnly);
	image.save(&outFile, "JPEG");


}

 I created a folder named images in my assets and I gave that path to save the image.Is the path given correct??

I cant find any image get saved on that folder.I tried to display the image as below

 

setImage( Image("images/temp1.bmp") );

 but nothing happens.Where Iam wrong.Plz help me out friend

Please use plain text.
Developer
DrShavargo
Posts: 133
Registered: ‎05-10-2013
My Device: Blackberry Z10
My Carrier: -

Re: save the downloaded images

Try and store it in one of the locations defined here. I'de suggest the shared folder, like in the code below, since it's fairly easy to access on the device. I don't know if your path is a correct one.

 

As a side not, this is the original code I pulled what I responded with from. It takes a QByteArray and trnsforms it into a QImage:

 

screen_read_window(winId->handle(), screen_buf, 0, NULL ,0);
QByteArray array;
nbytes = size[0] * size[1] * 4;
write_bitmap_header(nbytes, array, size);
for (int i = 0; i < size[1]; i++)
 	{
array.append(pointer + i * stride, size[0] * 4);
       	}
QImage image = QImage::fromData(array, "BMP");
QFile outFile("shared/photos/temp1.bmp");
outFile.open(QIODevice::WriteOnly);
image.save(&outFile, "JPEG");

 

----------------------------------------
Remember to mark the thread as solved at the post that solved your problem, and if you like a post, like it!
Please use plain text.
Developer
jmoukel
Posts: 111
Registered: ‎07-05-2012
My Device: none
My Carrier: MOvistar

Re: save the downloaded images

[ Edited ]

Hi SumiSadiq,

 

This is my code. I hope it helps you solve your problem. Let me know.

 

#include <QFile>

// This saves the image contained in the input "reply". It saves it in a different
//	 folder depending on the type of the request made to get the image.
// Returns true if the image was successfully saved. False otherwise. bool NetworkManager::saveImage(QNetworkReply* reply) { QString filePathWithName = "data/img/"; QString imageName; bool canSaveImage; bool canSaveInImgFolder; bool successfullySaved = false; // Creating the image folder (if no created yet) canSaveInImgFolder = createFolder("data/img/"); canSaveImage = canSaveInImgFolder; // Getting the (future) image name from a reply property set before imageName = getImageNameFromURL(reply->url().toString(), reply->property("askerManager").toInt()); // Deciding where to save the image if(reply->property("type") == DESTAQUE_IMAGE_REQUEST) { // Destaques Images bool canSaveInDestaquesFolder = createFolder("data/img/destaques"); canSaveImage = canSaveInDestaquesFolder; filePathWithName += "destaques/" + imageName; } else if(reply->property("type") == FILMES_IMAGE_REQUEST) { // Filmes Images bool canSaveInDestaquesFolder = createFolder("data/img/filmes"); canSaveImage = canSaveInDestaquesFolder; filePathWithName += "filmes/" + reply->property("id").toString() + ".jpg"; } // Saving the image on the device if(canSaveImage) successfullySaved = openAndSaveFile(filePathWithName, reply); // If the image was succesfully saved, we pass its local address to the originating object. if(successfullySaved) { QNetworkRequest req = reply->request(); QObject* origObj = req.originatingObject(); if(dynamic_cast<DataManager*> (origObj)) { ((DataManager*)origObj)->setLocalImage(filePathWithName, reply->property("askerPositionInList").toInt()); } } else { fprintf(stderr, "PROBLEM Failed to save Image: %s\n", filePathWithName.toLocal8Bit().data()); } return successfullySaved; } // Creates a sub-directory by using input "path" (e.g. "data/media/" to create the "media" folder inside the data folder). // Returns true on success. False otherwise. bool NetworkManager::createFolder(QString path) { bool r = true; QDir* dir = new QDir(); // Creating the sub directory (if not created yet) if(!dir->exists(path)) { r = dir->mkdir(path); if(r == false) { fprintf(stderr, "PROBLEM The folder %s could not be created \n", path.toLocal8Bit().data()); } else fprintf(stderr, "Successful creation of folder %s \n", path.toLocal8Bit().data()); } return r; } // This opens/creates a file which path+name is the value of the string "filePathWithName". // Then it fills this file with the response coming from the "reply" input parameter. Finally // it closes the file. bool NetworkManager::openAndSaveFile(QString filePathWithName, QNetworkReply* reply) { bool r = true; QFile *mFile = new QFile(filePathWithName); QNetworkRequest req = reply->request(); // Open the file and print an error if the file cannot be opened if (!mFile->open(QIODevice::WriteOnly)) { r = false; qDebug() << "\n Failed to open file"; fprintf(stderr, "PROBLEM Failed to open file: %s\n", filePathWithName.toLocal8Bit().data()); return r; } // Write to the file using the reply data and close the file mFile->write(reply->readAll()); mFile->flush(); mFile->close(); return r; }

 

Please use plain text.
Developer
RileyGB
Posts: 284
Registered: ‎08-06-2010
My Device: Z10

Re: save the downloaded images

Please note: you cannot save to your assets folder. You can save to your app's sandbox or data folder instead.



Follow me on twitter @RileyGB - https://twitter.com/RileyGB
View my BB10 OpenSource projects - https://github.com/RileyGB/BlackBerry10-Samples
Please use plain text.
Developer
SumiSadiq
Posts: 148
Registered: ‎04-08-2013
My Device: Blackberry 10
My Carrier: Blackberry

Re: save the downloaded images

[ Edited ]

Thanks a lot for your help,

Using your code I get the output "successfully created the folder" and "successfully saved image".But I cant view this image and no folder has been found.I tried the below code to display the image that is being saved.But nothing happens

if(successfullySaved)
	{
		qDebug()<<" succesfully saved image";

		//here I tried to display the image
	    setImage(Image(QUrl("file://" +filePathWithName )));

	}

 Is it possible to view the image that is being downloaded.How can I specify the path to display that image.Below is the code (I have made minor changes to your code) 

 

#include "WebImageView.h"
#include <QNetworkReply>
#include <QNetworkDiskCache>
#include <QDesktopServices>
#include <bb/cascades/Image>
#include <QFile>

using namespace bb::cascades;

QNetworkAccessManager * WebImageView::mNetManager = new QNetworkAccessManager();
QNetworkDiskCache * WebImageView::mNetworkDiskCache = new QNetworkDiskCache();

WebImageView::WebImageView() {

	// Initialize network cache
	mNetworkDiskCache->setCacheDirectory(QDesktopServices::storageLocation(QDesktopServices::CacheLocation));

	// Set cache in manager
	mNetManager->setCache(mNetworkDiskCache);

}

const QUrl& WebImageView::url() const {
	return mUrl;
}

void WebImageView::setUrl(const QUrl& url) {

	// Variables
	mUrl = url;
	mLoading = 0;

	// Reset the image
	resetImage();

	// Create request
	QNetworkRequest request;
	request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
	request.setUrl(url);

	// Create reply
	QNetworkReply * reply = mNetManager->get(request);
	QObject::connect(reply,SIGNAL(finished()), this, SLOT(imageLoaded()));
	QObject::connect(reply,SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(dowloadProgressed(qint64,qint64)));
	emit urlChanged();
}

double WebImageView::loading() const {
	return mLoading;
}

void WebImageView::imageLoaded()
{

	   // Get reply
		QNetworkReply * reply = qobject_cast<QNetworkReply*>(sender());

		// Process reply
		QByteArray imageData = reply->readAll();

		saveImage(reply);
}

void WebImageView::dowloadProgressed(qint64 bytes,qint64 total) {

	mLoading =  double(bytes)/double(total);
	emit loadingChanged();
}


// This saves the image contained in the input "reply". It saves it in a different
//	 folder depending on the type of the request made to get the image.
//       Returns true if the image was successfully saved. False otherwise.
bool WebImageView::saveImage(QNetworkReply* reply)
{
	//here I have changed the code to save to different folder as I want to save all the images in the same folder
	QString filePathWithName = "data/img/";
	QString imageName;
	bool canSaveImage;
	bool canSaveInImgFolder;
	bool successfullySaved = false;

	// Creating the image folder (if no created yet)
	canSaveInImgFolder = createFolder("data/img/");
	canSaveImage = canSaveInImgFolder;
	imageName = "defaultImage.jpg";
	filePathWithName += imageName;


	// Saving the image on the device
	if(canSaveImage)
	       successfullySaved = openAndSaveFile(filePathWithName, reply);


	// If the image was succesfully saved, we pass its local address to the originating object.
	if(successfullySaved)
	{
		qDebug()<<" succesfully saved image";

		//here I tried to display the image
	    setImage(Image(QUrl("file://" +filePathWithName )));

	}
	else
	{
		fprintf(stderr, "PROBLEM Failed to save Image: %s\n", filePathWithName.toLocal8Bit().data());
	}

	return successfullySaved;
}


// Creates a sub-directory by using input "path" (e.g. "data/media/" to create the "media" folder inside the data folder).
//   Returns true on success. False otherwise.
bool WebImageView::createFolder(QString path)
{
	bool r = true;
	QDir* dir = new QDir();

	// Creating the sub directory (if not created yet)
	if(!dir->exists(path))
	{
		r = dir->mkdir(path);

		if(r == false)
		{
			qDebug()<<" PROBLEM The folder %s could not be created \n", path.toLocal8Bit().data();
			fprintf(stderr, "PROBLEM The folder %s could not be created \n", path.toLocal8Bit().data());
		}
		else
		{
			qDebug()<<" Successful creation of folder %s \n", path.toLocal8Bit().data();
			fprintf(stderr, "Successful creation of folder %s \n", path.toLocal8Bit().data());
		}
	}

	return r;
}

// This opens/creates a file which path+name is the value of the string "filePathWithName".
//   Then it fills this file with the response coming from the "reply" input parameter. Finally
//	 it closes the file.
bool WebImageView::openAndSaveFile(QString filePathWithName, QNetworkReply* reply)
{
	bool r = true;
	QFile *mFile = new QFile(filePathWithName);
	QNetworkRequest req = reply->request();

	// Open the file and print an error if the file cannot be opened
	if (!mFile->open(QIODevice::WriteOnly))
	{
		r = false;
		qDebug() << " Failed to open file";
		fprintf(stderr,
				"PROBLEM Failed to open file: %s\n",
				filePathWithName.toLocal8Bit().data());
		return r;
	}

	// Write to the file using the reply data and close the file
	mFile->write(reply->readAll());
	mFile->flush();
	mFile->close();

	return r;
}

 Plz help me out friend

 

Please use plain text.
Trusted Contributor
smjose
Posts: 134
Registered: ‎04-12-2013
My Device: BB Z10
My Carrier: Telenor

Re: save the downloaded images

Try this out..

 

pass your imageData in your saveImage function as QByteArray

 

if(successfullySaved)
	{
		qDebug()<<" succesfully saved image";

		//here I tried to display the image
	    setImage(Image(QUrl(QDir::home() +/data/img/defaultImage.jpg)));

	}

 

Please like this if you are answered.
Please use plain text.
Developer
jmoukel
Posts: 111
Registered: ‎07-05-2012
My Device: none
My Carrier: MOvistar

Re: save the downloaded images

[ Edited ]

Hi SumiSadiq,

 

First of all, if you haven't yet, I think you should check if the image was saved in the device/simulator. To do so, in QNX Momentics IDE, go to Window --> Show View --> Target File System Navigator. In this window navigates in the file system this way device/simulator --> Sandboxes --> com.yourorg.yourappname.whatever --> data --> img. Then check if the image you wanted to download is in that folder. If so, then try open it in a image viewer to see if you can visualize it and it's not corrupted or somthing like that.

 

Second, if the image is successfully saved, then probably the problem is in your setImage(...) function. What are you doing in that function? Can I see the code?

Please use plain text.
Developer
SumiSadiq
Posts: 148
Registered: ‎04-08-2013
My Device: Blackberry 10
My Carrier: Blackberry

Re: save the downloaded images

Thanks a lot guys for your help,

I figured out the problem.The problem was with the path that I used in setImage().

Please use plain text.