Saturday, June 8, 2013

Using QML Camera and passing image to C++ code

I tried to compile one my application with Qt5. Application was using QML camera and sharing image to C++ code for further processing.

Following is sample code, it works with Qt5 and Qt Multimedia 5.

Lets start with ImageProcessor class, the C++ class which is called from QML to further image processing.

Following is header file for ImageProcessor class, it declares processImage() slot which can be invoked from QML code.
#ifndef IMAGEPROCESSOR_H
#define IMAGEPROCESSOR_H

#include <QObject>

class ImageProcessor : public QObject
{
    Q_OBJECT
public:
    explicit ImageProcessor(QObject *parent = 0);
 
public slots:
    void processImage( const QString& image);   
};
#endif // IMAGEPROCESSOR_H
Following is cpp file for ImageProcessor class. processImage() function retrieves Image from camera image provider. Once we have valid image, we can process it further.
#include "imageprocessor.h"
#include <QtQml/QmlEngine>
#include <QtQml/QmlContext>
#include <QtQuick/QQuickImageProvider>
#include <QDebug>

ImageProcessor::ImageProcessor(QObject *parent)
    : QObject(parent)
{}

void ImageProcessor::processImage( const QString& path)
{
    QUrl imageUrl(path);
    QQmlEngine* engine = QQmlEngine::contextForObject(this)->engine();
    QQmlImageProviderBase* imageProviderBase = engine->imageProvider(
     imageUrl.host());
    QQuickImageProvider* imageProvider = static_cast<QQuickImageProvider>
     (imageProviderBase);
    
    QSize imageSize;
    QString imageId = imageUrl.path().remove(0,1);
    QImage image = imageProvider->requestImage(imageId, &imageSize, imageSize);
    if( !image.isNull()) {
        //process image
    }
}
Now we need to register ImageProcessor class with QML. so that we can use it from QML code. This can be done by using qmlRegisterType global function.
#include  <QtGui/QGuiApplication>
#include  <QQmlEngine>
#include  <QQmlComponent>
#include  <QtQuick/QQuickView>

#include "imageprocessor.h"

int main(int argc, char *argv[])
{
    qmlRegisterType<ImageProcessor>("ImageProcessor", 1, 0, "ImageProcessor");

    QGuiApplication app(argc, argv);

    QQuickView view;

    QObject::connect(view.engine(),SIGNAL(quit()),&app,SLOT(quit()));    
    view.setSource(QUrl::fromLocalFile("qml/main.qml"));
    view.show();

    return app.exec();
}
That's all from C++ side, QML code is event easier. Following how you can use ImageProcess class from QML code.
import QtQuick 2.0
import QtMultimedia 5.0
import ImageProcessor 1.0

Rectangle {
    width: 360
    height: 360

    //shows live preview from camera
    VideoOutput {
        source: camera
        anchors.fill: parent
        focus : visible
    }

    //shows captured image
    Image {
        id: photoPreview
        anchors.fill: parent
        fillMode: Image.PreserveAspectFit
    }

    Camera {
        id: camera
        imageProcessing.whiteBalanceMode: CameraImageProcessing.WhiteBalanceFlash
        captureMode: Camera.CaptureStillImage

        exposure {
            exposureCompensation: -1.0
            exposureMode: Camera.ExposurePortrait
        }

        flash.mode: Camera.FlashRedEyeReduction

        imageCapture {
            onImageCaptured: {
                photoPreview.source = preview
                imageProcessor.processImage(preview);
            }
        }
    }

    MouseArea{
        anchors.fill: parent
        onClicked: {
            camera.imageCapture.capture();
        }
    }

    //image processor for further image processing
    ImageProcessor{
        id: imageProcessor
    }
}

Thursday, June 6, 2013

VMWare Workstation 9.0.1 on Ubuntu 13.04

I recently upgraded my Ubuntu machine to Ubuntu 13.04.  Update went smoothly and all my usual application worked fine. But after some time I needed to use VMWare workstation and I realized its not working any more.

I got following error.


This is caused by some header location changes. This can be resolved by following command.

sudo ln -s /usr/src/linux-headers-$(uname -r)/include/generated/uapi/linux/version.h /usr/src/linux-headers-$(uname -r)/include/linux/version.h

Once this is done, you will need to compile and install VMware modules. When I pressed install button, nothing was happening.


To check I tried to compile modules from command line.

sudo vmware-modconfig --console --install-all

But this was throwing many compilation error, anyway I found this script which make above process easier, It make link for kernel header to expected location and then build VMWare modules. You can find more details about script here.

This script seems to be working but still there was some error in driver.c file. I was getting following errors.

make[1]: Entering directory `/usr/src/linux-headers-3.8.0-23-generic'
  CC [M]  /tmp/modconfig-IBc3U5/vmci-only/linux/driver.o
  CC [M]  /tmp/modconfig-IBc3U5/vmci-only/linux/vmciKernelIf.o
  CC [M]  /tmp/modconfig-IBc3U5/vmci-only/common/vmciContext.o
  CC [M]  /tmp/modconfig-IBc3U5/vmci-only/common/vmciDatagram.o
/tmp/modconfig-IBc3U5/vmci-only/linux/driver.c:1754:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘vmci_probe_device’
/tmp/modconfig-IBc3U5/vmci-only/linux/driver.c:1982:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘vmci_remove_device’
/tmp/modconfig-IBc3U5/vmci-only/linux/driver.c:119:12: warning: ‘vmci_probe_device’ used but never defined [enabled by default]
/tmp/modconfig-IBc3U5/vmci-only/linux/driver.c:121:13: warning: ‘vmci_remove_device’ used but never defined [enabled by default]
/tmp/modconfig-IBc3U5/vmci-only/linux/driver.c:2063:1: warning: ‘vmci_interrupt’ defined but not used [-Wunused-function]
/tmp/modconfig-IBc3U5/vmci-only/linux/driver.c:2137:1: warning: ‘vmci_interrupt_bm’ defined but not used [-Wunused-function]
/tmp/modconfig-IBc3U5/vmci-only/linux/driver.c:1717:1: warning: ‘vmci_enable_msix’ defined but not used [-Wunused-function]
make[2]: *** [/tmp/modconfig-IBc3U5/vmci-only/linux/driver.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [_module_/tmp/modconfig-IBc3U5/vmci-only] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.8.0-23-generic'

To resolve those error you will need this kernel patch, this patch is for 3.8.0 kernel, it might not work for you. You can find more information about this patch here. To apply patch follow following steps.

1. cd /usr/lib/vmware/modules/source
2. tar -xf vmci.tar
3. cd vmci-only
4. patch -p1 < 'patchfile'
5. cd ..
6. tar -cf vmci.tar vmci-only/
7. vmware-modconfig --console --install-all
8. rm -rf vmci-only/

Once you applied above patch, VMWare module should compile fine. I ran above script, which link kernel header and build VMware module, and then I was able to use VMWare workstation.

Still there was one last hurdle, When I tried to run my virtual machine, it asked for serial number, But when I tried to enter serial number, Dialog for entering serial number was not getting launched.

To resolve those I need to supply serial number from terminal, using following command.

/usr/lib/vmware/bin/vmware-vmx --new-sn 123-123-123-123...123

Finally, I was able to use my virtual machine. I guess if you rely on virtual machine heavily, then its better to avoid Ubuntu/Kernel upgrade.

Sunday, May 26, 2013

Converting APK to BAR and deploying it to BB10 device

As you might know BB10 device support Android application. But to install Android application on BB10, first you need to convert .apk file to .bar file.

I already have install BB10 NDK (Native Development Kit ), so I did not struggled with installing certificate file and setup the signer. BB10 NDK installer and IDE did that for me.

You will also need android sdk installed on your pc, before you begin. You can find detailed instruction here at BlackBerry Development site.

Following are few steps that I often use to convert APK to BAR file.

1) export ANDOID_HOME varible

export ANDROID_HOME=~/android_sdk/sdk/

2) Verify if APK file does not you unsupported APIs.

 ./apk2barVerifier ./ANDROID_APPLICATION.apk 

3) If your APK does not use unsupported APIs then you can go ahead and covert APK to BAR to test on your device.

./apk2bar ./ANDROID_APPLICATION.apk -d DEBUG_TOKEN_FILE 

4) Install BAR file to development device.

Following will deploy all BAR files under test folder to device.I find this method easier.

./batchbar-deploy ~/Desktop/test 169.254.0.1 DEVICE_DEVELOPMENT_PASSWORD

Or you can deply individual BAR file using following command.

 ./blackberry-deploy -installapp -package ./BAR_FILE.bar -device 169.254.0.1 -password DEVICE_DEVELOPMENT_PASSWORD

Once testing is done, you can use blackberry-signer command to sign BAR file and publish it on App World. But I did not tried it my self. I just wanted to install one android app on my BB10 and my device is always on development mode so I just used BAR files with Debug token.

Saturday, May 4, 2013

Un-boxing BlackBerry Limited Edition Red Z10

Last week I received Limited Edition Red Z10 device. I was waiting for it for quite long time and finally received it last week.

Following are Un-boxing of the device. The box is quite different than box in which Dev Alpha device came.



Box came with a Device, an USB cable, Power adapters compatible with various countries' standard and a headphone.


Behind the battery there is slot for micro SIM and There is also slot for micro SD card, you don't need to remove battery to change micro SD card.


It has hardware button to control volume and play pause key in middle and on other side there are slots for micro USB and micro HDMI port.




Its take some time for complete boot up, once it boots up and initial set-up is complete it offers a introductory tutorial for its gestures based interface.

Sunday, April 21, 2013

Un-boxing BlackBerry 10 Dev Alpha C

After a long wait, finally today I received my BlackBerry 10 Dev Alpha C device. As you know it developer version of BlackBerry 10 Qwerty device.

Following are few pics from ub-boxing, if you are curious about how device looks and what comes with it.

It comes in nice little box, same as Dev Alpha B, with Micro USB cable and Power cable.



Build quality wise its also boxy and made from plastic.



On one side , there is micro USB port for data transfer and charging and micro HDMI for TV out, on other side there are media keys, on top there is audio jack and power button.


Here are few snaps after power on.