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
New Developer
vladest
Posts: 88
Registered: ‎06-16-2012
My Device: N950/E7/N808/N9/X7/BB10 Alpha
My Carrier: Kievstar

Re: Container showing QImage

great

can you please share the scaler code if this acceptable for you?

Qt/Symbian/Meego/BB10/Cascades developer
Please use plain text.
Developer
Dredvard
Posts: 160
Registered: ‎01-27-2012
My Device: Playbook
My Carrier: Rogers

Re: Container showing QImage

Sure.  Haven't cleaned it up.  I'll share it one condition.  If you improve it you post it here.

 

/*
 * ImageScaler.cpp
 *
 *  Created on: Oct 14, 2012
 *      Author: Ed
 */

#include <bb/cascades/ImageTracker>

#include "ImageScaler.hpp"

ImageScaler::ImageScaler(QObject* parent) {

	bool result = QObject::connect(this,
			SIGNAL(imageSourceChanged(const QString & )), this,
			SLOT(onImageSourceChanged(const QString &)));

	Q_ASSERT(result);
	Q_UNUSED(result);
	mImageTracker = NULL;
	qDebug() << "Creation";
}

ImageScaler::~ImageScaler() {
}

QString ImageScaler::imageSource() {
	return mImageSource;
}

void ImageScaler::setImageSource(QString qString) {
	qDebug() << "Setting ImageSource";
	mImageSource = qString;
	emit imageSourceChanged(qString);
}

void ImageScaler::onImageSourceChanged(const QString & imageSource) {
	qDebug() << "onImageSourceChanged";
	int length =200;
//	Image im=ScaledImage(imageSource, length);
	mImage=QVariant::fromValue(ScaledImage(imageSource, length));
	qDebug() << "QVariant";
	emit imageChanged(mImage);
	qDebug() << "emitted";
/*
		mImageTracker = new ImageTracker(imageSource);
		bool result = connect(mImageTracker,
				SIGNAL(stateChanged(bb::cascades::ResourceState::Type )), this,
				SLOT(onStateChanged(bb::cascades::ResourceState::Type )));
		Q_ASSERT(result);
		Q_UNUSED(result);
		result = connect(this, SIGNAL(imageScaled()), mImageTracker,
				SLOT(deleteLater()));

		Q_ASSERT(result);
		Q_UNUSED(result);
*/
}
//returns unmirroed image
static bb::cascades::Image fromQImage(const QImage &qImage) {
	bb::ImageData imageData(bb::PixelFormat::RGBA_Premultiplied, qImage.width(),
			qImage.height());

	unsigned char *dstLine = imageData.pixels();
	for (int y = 0; y < imageData.height(); y++) {
		unsigned char * dst = dstLine;
		for (int x = 0; x < imageData.width(); x++) {
			QRgb srcPixel = qImage.pixel(x, y);
			*dst++ = qRed(srcPixel);
			*dst++ = qGreen(srcPixel);
			*dst++ = qBlue(srcPixel);
			*dst++ = qAlpha(srcPixel);
		}
		dstLine += imageData.bytesPerLine();
	}

	return imageData;
}
// Returns an image with the given length and tries to load the image from the
// file with the given file_name.
Image ImageScaler::ScaledImage(const QString &file_name, int length) {
	QDir app("app/native/assets");
//	QString filestr = fileInfo.absoluteFilePath();
	QString relpath = app.absoluteFilePath(file_name);
	QImageReader image_reader(relpath);
	if (!image_reader.canRead()) {
		qDebug() << "Can't read " << relpath;
		QImage image;
		return fromQImage(image);
	}

	int image_width = image_reader.size().width();
	int image_height = image_reader.size().height();
	if (image_width > image_height) {
		image_height = static_cast<double>(length) / image_width * image_height;
		image_width = length;
	} else if (image_width < image_height) {
		image_width = static_cast<double>(length) / image_height * image_width;
		image_height = length;
	} else {
		image_width = length;
		image_height = length;
	}
	image_reader.setScaledSize(QSize(image_width, image_height));
	return fromQImage(image_reader.read());
}

void ImageScaler::onStateChanged(bb::cascades::ResourceState::Type  state) {

	if (state == bb::cascades::ResourceState::Loaded) {
		qDebug() << "image Loaded";
		emit imageLoaded();
	}
}
void ImageScaler::onImageLoaded() {

	emit imageScaled();
}

void ImageScaler::onImageScaled(){
}

QVariant ImageScaler::trackedImage() const {
	return mImage;
}
/*
void ImageScaler::imageChanged(const QVariant& image) {
}
*/

 

---
If you find my post helpful please "like" it and "accept as a solution"
Please use plain text.
New Contributor
vincentkwok
Posts: 2
Registered: ‎02-21-2013
My Device: BB10 Dev Alpha B
My Carrier: RIM

Re: Container showing QImage

[ Edited ]

[solved]

 

I add your code(as same as http://developer.blackberry.com/cascades/reference/bb__imagedata.html) into my program, but it cannot be compiled for unknown reason. Here is console log:


**** Build of configuration Device-Debug for project mytest-bb- ****

make Device-Debug
make -C .//translations -f Makefile update
make[1]: Entering directory `/Users/jplus/ndk-10.0.9-workspace/mytest-bb-/translations'
/Applications/bbndk/host_10_0_9_404/darwin/x86/usr/bin/lupdate mytest_BB.pro
Updating 'mytest_BB.ts'...
Found 0 source text(s) (0 new and 0 already existing)
make[1]: Leaving directory `/Users/jplus/ndk-10.0.9-workspace/mytest-bb-/translations'
make -C .//translations -f Makefile release
make[1]: Entering directory `/Users/jplus/ndk-10.0.9-workspace/mytest-bb-/translations'
/Applications/bbndk/host_10_0_9_404/darwin/x86/usr/bin/lrelease mytest_BB.pro
Updating '/Users/jplus/ndk-10.0.9-workspace/mytest-bb-/translations/mytest_BB.qm'...
Generated 0 translation(s) (0 finished and 0 unfinished)
make[1]: Leaving directory `/Users/jplus/ndk-10.0.9-workspace/mytest-bb-/translations'
make -C ./arm -f Makefile debug
make[1]: Entering directory `/Users/jplus/ndk-10.0.9-workspace/mytest-bb-/arm'
make -f Makefile.Debug
make[2]: Entering directory `/Users/jplus/ndk-10.0.9-workspace/mytest-bb-/arm'
qcc -Vgcc_ntoarmv7le -c -Wc,-include -Wc,o.le-v7-g/.obj/mytest_BB -Wno-psabi -lang-c++ -fstack-protector-strong -mcpu=cortex-a9 -g -Wno-psabi -Wall -W -D_REENTRANT -DQT_NO_IMPORT_QT47_QML -DQ_OS_BLACKBERRY -DQT_DECLARATIVE_DEBUG -DQT_DECLARATIVE_LIB -DQT_CORE_LIB -DQT_SHARED -I/Applications/bbndk/target_10_0_9_1673/qnx6/usr/share/qt4/mkspecs/blackberry-armv7le-qcc -I../../mytest-bb- -I/Applications/bbndk/target_10_0_9_1673/qnx6/usr/include/qt4/QtCore -I/Applications/bbndk/target_10_0_9_1673/qnx6/usr/include/qt4/QtDeclarative -I/Applications/bbndk/target_10_0_9_1673/qnx6/usr/include/qt4 -I../src/Player -I../src -Io.le-v7-g/.moc -I/Applications/bbndk/target_10_0_9_1673/qnx6/usr/include -I/Applications/bbndk/target_10_0_9_1673/qnx6/usr/include/freetype2 -I. -o o.le-v7-g/.obj/mytestBB.o ../src/mytestBB.cpp
../src/mytestBB.cpp: In function 'bb::ImageData fromQImage(const QImage&)':
../src/mytestBB.cpp:361:1: warning: no return statement in function returning non-void [-Wreturn-type]
qcc -Vgcc_ntoarmv7le -lang-c++ -Wl,-rpath-link,/Applications/bbndk/target_10_0_9_1673/qnx6/armle-v7/lib -Wl,-rpath-link,/Applications/bbndk/target_10_0_9_1673/qnx6/armle-v7/usr/lib -Wl,-rpath-link,/Applications/bbndk/target_10_0_9_1673/qnx6/armle-v7/usr/lib/qt4/lib -o o.le-v7-g/mytest_BB o.le-v7-g/.obj/mytestBB.o o.le-v7-g/.obj/Player.o o.le-v7-g/.obj/main.o o.le-v7-g/.obj/moc_mytestBB.o -L/Applications/bbndk/target_10_0_9_1673/qnx6/armle-v7/lib -L/Applications/bbndk/target_10_0_9_1673/qnx6/armle-v7/usr/lib -L/Applications/bbndk/target_10_0_9_1673/qnx6/armle-v7/usr/lib/qt4/lib -L/Applications/bbndk/target_10_0_9_1673/qnx6//usr/lib/qt4/lib -lbbcascades -lQtDeclarative -lQtScript -lQtSvg -lQtSql -lsqlite3 -lz -lQtXmlPatterns -lQtGui -lQtNetwork -lsocket -lQtCore -lm -lbps
/Applications/bbndk/host_10_0_9_404/darwin/x86/usr/bin/ntoarm-ld: o.le-v7-g/.obj/mytestBB.o: undefined reference to symbol '_ZN2bb9ImageDataC1ENS_11PixelFormat4TypeEii'
/Applications/bbndk/host_10_0_9_404/darwin/x86/usr/bin/ntoarm-ld: note: '_ZN2bb9ImageDataC1ENS_11PixelFormat4TypeEii' is defined in DSO /Applications/bbndk/target_10_0_9_1673/qnx6/armle-v7/usr/lib/libbb.so.1 so try adding it to the linker command line
/Applications/bbndk/target_10_0_9_1673/qnx6/armle-v7/usr/lib/libbb.so.1: could not read symbols: Invalid operation
cc: /Applications/bbndk/host_10_0_9_404/darwin/x86/usr/bin/ntoarm-ld error 1
make[2]: *** [o.le-v7-g/mytest_BB] Error 1
make[1]: *** [debug] Error 2
make[2]: Leaving directory `/Users/jplus/ndk-10.0.9-workspace/mytest-bb-/arm'
make: *** [Device-Debug] Error 2
make[1]: Leaving directory `/Users/jplus/ndk-10.0.9-workspace/mytest-bb-/arm'

**** Build Finished ****

 It only shows me Error 2 and Error 1. I don't know where am I wrong.

 

I found below is the problematic code. The program can be compiled if I comment it. 

bb::ImageData imageData(bb::PixelFormat::RGBA_Premultiplied, qImage.width(), qImage.height());

 

Please use plain text.
Developer
Zmey
Posts: 1,511
Registered: ‎12-18-2012
My Device: PlayBook, Z10, DAC

Re: Container showing QImage

Hi,

Add
LIBS += -lbb
to .pro file.

Andrey Fidrya, @zmeyc on twitter
Please use plain text.
New Contributor
vincentkwok
Posts: 2
Registered: ‎02-21-2013
My Device: BB10 Dev Alpha B
My Carrier: RIM

Re: Container showing QImage

Thanks, that is a solution I finally found. 

 

However, I am in troblem in terms of performance.

Acutally, I am working on touch and draw function in my app. The method "fromQImage" is overloaded so it slows down the app. e.g. if my resolution is 1024x768, it has to loop nearly 800k to generate ImageData. Do you have any suggestion to make a quick conversion? All I want to do is to draw a path with (x,y) and make it to be a ImageView in a Container.

Please use plain text.
Developer
Dredvard
Posts: 160
Registered: ‎01-27-2012
My Device: Playbook
My Carrier: Rogers

Re: Container showing QImage

imageScribble::imageScribble(QObject * Parent=0):
	m_painting(false){
//	 m_qimage= QImage(1280,768,QImage::Format_ARGB32);
	 m_qimage= QImage(768,1280,QImage::Format_ARGB32);
	 clearImage();
    myPenColors
            << QColor("green")
            << QColor("purple")
            << QColor("red")
            << QColor("blue")
            << QColor("yellow")

            << QColor("pink")
            << QColor("orange")
            << QColor("brown")
            << QColor("grey")
            << QColor("black");

}


// Setter for Properties

void imageScribble::setObject(const QString &object) {
	if (m_object == object)
		return;

	m_object = object;
	emit objectChanged();

	updateImage();
}
//! [1]



void imageScribble::setPainting(bool painting) {
	if (m_painting == painting)
		return;

	m_painting = painting;
	emit paintingChanged();
}
//! [1]


// Properties

bool imageScribble::painting() const {
	return m_painting;
}

QString imageScribble::object() const {
	return m_object;
}

QRectF imageScribble::layoutFrame() const {
	return m_layoutFrame;
}

bb::cascades::Image imageScribble::image() const {
	return m_image;
}

/*
 * Return the size we need for the image that is to be replicated
 */
//! [4]
QSize imageScribble::desiredBoardSize() const {
	const int numPixelsX = workingImageSize.width();
	const int numPixelsY = workingImageSize.height();
	return QSize(numPixelsX, numPixelsY);
}
//! [4]
/*
 * Update the ImageView with the replicated stamps or images
 */
//! [5]
void imageScribble::updateImage() {

	const QImage finalImage = m_qimage.rgbSwapped();

	const bb::ImageData imageData = bb::ImageData&colon;:fromPixels(finalImage.bits(),
//			bb::PixelFormat::RGBX, finalImage.width(), finalImage.height(),
			bb::PixelFormat::RGBA_Premultiplied, finalImage.width(), finalImage.height(),
			finalImage.bytesPerLine());

	m_image = bb::cascades::Image(imageData);
	emit imageChanged();
}


void imageScribble::clearImage(){
    m_qimage.fill(qRgba(0,0,0,0));
//   modified = true;
    updateImage();
}

//
// Slots
//

void imageScribble::onImageTouch(bb::cascades::TouchEvent *event) {
	if(m_painting){
	float imagex = event->windowX()/m_layoutFrame.width()*m_qimage.width();
	float imagey = event->windowY()/m_layoutFrame.height()*m_qimage.height();

	QPointF imagexy(imagex,imagey);
	QPainter painter(&m_qimage);
	if (event->isDown()) {

//		painter.setPen(Qt::NoPen);
//		painter.setBrush(myPenColors.at(1 % myPenColors.count()));
//		painter.drawEllipse(QPointF(x,y),5,5);

		m_qpointf=imagexy;
	}
	else if (event->isMove()){
	    painter.setRenderHint(QPainter::Antialiasing, true);
	    painter.setPen(QPen(Qt::darkRed, 10));
	    painter.drawLine(m_qpointf, imagexy);
	    m_qpointf=imagexy;


	}
	else if (event->isUp()){
	    painter.setRenderHint(QPainter::Antialiasing, true);
	    painter.setPen(QPen(Qt::darkRed, 10));
	    painter.drawLine(m_qpointf, imagexy);
//		painter.drawEllipse(QPointF(x,y),5,5);
//		painter.end();

	}
	updateImage();
	}
}

void imageScribble::handleLayoutFrameUpdated(QRectF layoutFrame){
	if (m_layoutFrame==layoutFrame)
		return;
	m_layoutFrame = layoutFrame;
	emit layoutFrameChanged();
//	updateImage();
}

   Here's an alternate way however I too am having response issues.  Haven't had  a chance to optimize it yet.  Thought it was the TouchEvent response time when using signal/slot that was causing the lag - but just haven't had a chance to look into it further.  I would be interested in hearing how you accomplished it.

---
If you find my post helpful please "like" it and "accept as a solution"
Please use plain text.