-
-
Save nbergont/8963892 to your computer and use it in GitHub Desktop.
import QtQuick 2.0 | |
import Qt.labs.folderlistmodel 2.0 | |
/** | |
--- QML Ken Burns slideshow --- | |
Work well on Raspberry Pi (resize image 1920*1600 max before ...) | |
call : | |
qmlscene slideshow.qml path="/home/img" | |
qmlscene.exe slideshow.qml path="/C:/test/img" | |
**/ | |
Rectangle { | |
id: root | |
width: 800 | |
height: 600 | |
color: "black" | |
focus: true | |
Keys.onEscapePressed :{ | |
Qt.quit(); | |
} | |
//Slideshow options : | |
property int slide_duration: 7000 //ms | |
property int fade_duration: 800 | |
//Load 2 slides | |
Loader {id:img1; transformOrigin: Item.TopLeft; sourceComponent: slide;} | |
Loader {id:img2; transformOrigin: Item.TopLeft; sourceComponent: slide;} | |
property variant current_img: img1 | |
//Input images files | |
FolderListModel{ | |
id: img_files | |
folder : "file://" + Qt.application.arguments[2].split("=")[1] | |
nameFilters: ["*.jpg", "*.jpeg", "*.png"] | |
showDirs : false | |
property int index: 0 | |
property variant rlist: [] | |
function getNextUrl(){ | |
if(index >= rlist.length) | |
shuffleList(); | |
return img_files.get(rlist[index++], "fileURL"); //filePath | |
} | |
//Fisher-Yates shuffle algorithm. | |
function shuffleArray(array) { | |
for (var i = array.length - 1; i > 0; i--) { | |
var j = Math.floor(Math.random() * (i + 1)); | |
var temp = array[i]; | |
array[i] = array[j]; | |
array[j] = temp; | |
} | |
return array; | |
} | |
function shuffleList() | |
{ | |
console.log("Shuffle..."); | |
var list = []; | |
for(var i=0; i<img_files.count; i++) | |
list.push(i); | |
shuffleArray(list); | |
rlist = list; | |
index = 0; | |
} | |
//Initialisation | |
onDataChanged: { | |
console.log(img_files.count+ " images found"); | |
shuffleList(); | |
//Force la lecture de la 1ere image | |
img1.item.asynchronous = false | |
img1.item.visible = true; | |
img1.item.load_next_slide(); | |
img2.item.load_next_slide(); | |
img1.item.asynchronous = true; | |
mtimer.start(); | |
} | |
} | |
//Main timer | |
Timer{ | |
id:mtimer | |
interval: slide_duration-fade_duration | |
repeat: true | |
triggeredOnStart : true | |
onTriggered: { | |
current_img.item.fadein(); | |
current_img = (current_img == img1 ? img2 : img1); //Swap img | |
current_img.item.fadeout(); | |
} | |
} | |
//Slide component | |
Component { | |
id: slide | |
Image { | |
id: img | |
asynchronous : true | |
cache: false | |
fillMode: Image.PreserveAspectFit | |
//visible: true | |
opacity: 0 | |
width: root.width | |
height: root.height | |
//Max painted size (RPI limitations) | |
sourceSize.width: 1920 | |
sourceSize.height: 1600 | |
property real from_scale: 1 | |
property real to_scale: 1 | |
property real from_x: 0 | |
property real to_x: 0 | |
property real from_y: 0 | |
property real to_y: 0 | |
function randRange(a, b){return Math.random()*Math.abs(a-b) + Math.min(a,b);} | |
function randChoice(n){return Math.round(Math.random()*(n-1));} | |
function randDirection(){return (Math.random() >= 0.5) ? 1 : -1;} | |
function fadein(){ | |
//Check image loading... | |
if(status != Image.Ready){ | |
console.log("LOAD ERROR", source); | |
return; | |
} | |
//Fit in view | |
var img_ratio = paintedWidth/paintedHeight; | |
var scale = (height == paintedHeight) ? width/paintedWidth : height/paintedHeight; | |
//Find random directions | |
if(img_ratio < 1){ //Rotated | |
from_scale = scale*0.8;//Un-zoom on 16/9 viewer... | |
to_scale = from_scale; | |
from_y = 0; | |
to_y = 0; | |
from_x = randDirection()*(paintedHeight*from_scale-height)/2; | |
to_x = 0; | |
} | |
else if(img_ratio > 2){ //Panorama | |
from_scale = scale; | |
to_scale = from_scale; | |
from_y = randDirection()*(paintedWidth*from_scale-width)/2; | |
to_y = -from_y; | |
from_x = 0; | |
to_x = 0; | |
} | |
else { //Normal | |
var type = randChoice(3); | |
switch(type) | |
{ | |
case 0: //Zoom in | |
from_scale = scale; | |
to_scale = scale*1.4; | |
from_y = 0; | |
to_y = 0; | |
from_x = 0; | |
to_x = 0; | |
break; | |
case 1: //Zoom out | |
from_scale = scale*1.4; | |
to_scale = scale; | |
from_y = 0; | |
to_y = 0; | |
from_x = 0; | |
to_x = 0; | |
break; | |
default: //Fixed zoom | |
from_scale = scale*1.2; | |
to_scale = from_scale; | |
break; | |
} | |
//Random x,y | |
var from_max_y = (paintedWidth*from_scale-width)/2; | |
var to_max_y = (paintedWidth*to_scale-width)/2; | |
from_y = randRange(-from_max_y, from_max_y); | |
to_y = randRange(-to_max_y, to_max_y); | |
var from_max_x = (paintedHeight*from_scale-height)/2; | |
var to_max_x = (paintedHeight*to_scale-height)/2; | |
from_x = randRange(-from_max_x, from_max_x); | |
to_x = randRange(-to_max_x, to_max_x); | |
} | |
visible = true; | |
afadein.start(); | |
} | |
function fadeout(){ | |
afadeout.start(); | |
} | |
function load_next_slide(){ | |
visible = false; | |
source = img_files.getNextUrl(); | |
console.log(source); | |
} | |
ParallelAnimation{ | |
id: afadein | |
NumberAnimation {target: img; property: "opacity"; from: 0; to: 1; duration: fade_duration; easing.type: Easing.InOutQuad;} | |
NumberAnimation {target: img; property: "y"; from: from_x; to: to_x; duration: slide_duration; } | |
NumberAnimation {target: img; property: "x"; from: from_y; to: to_y; duration: slide_duration; } | |
NumberAnimation {target: img; property: "scale"; from: from_scale; to: to_scale; duration: slide_duration; } | |
} | |
SequentialAnimation { | |
id: afadeout; | |
NumberAnimation{ target: img; property: "opacity"; from: 1; to: 0; duration: fade_duration; easing.type: Easing.InOutQuad;} | |
ScriptAction { script: img.load_next_slide(); } | |
} | |
} | |
} | |
} |
It is the limitation of Raspberry Pi texture size ! (exact limit is 2048*2048)
Hi!
I am quite new to Qt/QML but your source is a good inspiration - I wonder, if somebody could tell me, how I could include "QtGraphicalEffects" such as "HueSaturation" into the QML? I just wanted to use them to apply some "filters" to adjust brightness, contrast etc.
Thanks a lot,
Sven
Thank you, this works really well.
I'm completely new to Qt/QML and struggled to get qmlscene working initially. For some reason I couldn't get the hardware acceleration to work in Jessie. However, I found a prebuilt version of Qt5 for Raspbian Wheezy and some instructions at the following page https://www.raspberrypi.org/forums/viewtopic.php?t=70784&p=526245
Thanks again for posting this.
Hi,
can someone explain to me, where the following limitation for the RPI comes from ( code lines 111-113)?
Thanks a lot,
Ben