Archives pour la categorie ‘Java’

Widget Androïd : customisation des barres de progression horizontales

Je me suis amusé à réaliser un simple widget pour Androïd. J’ai consulté un peu de documentation en ligne, d’exemples et honnêtement ce n’est pas cela qui manque.

L’objectif de ce premier programme était de comprendre comment fonctionnent les widgets car leur approche est un peu différente des programmes classiques basés sur les « activities ».

Ce premier widget rend un service très simple, il affiche la place disponible sur votre carte SD et la mémoire interne. Tout cela accessible sur le bureau en un seul coup d’oeil.

Dans ce post je ne vais pas décrire comment créer un widget sous Androïd, les exemples sont nombreux sur la toile. Je vais plutôt décrire la résolution d’un point m’ayant posé problème :

  • la customisation des barres de progression horizontales.

En effet, par défaut les barres de progression horizontales offrent assez peut de paramètres : elles sont larges et jaunes sur fond gris. Souhaitant afficher une barre verte sur fond rouge, dans un espace minuscule (48 pixels sur 48 pixels), j’ai été contraint de dépasser les paramètres de base.

Pour ce faire, après quelques recherches, il faut récupérer le fichier natif décrivant les barres de progression horizontales, le modifier et l’intégrer au projet.

Récupérer le fichier natif

Pour récupérer ce fichier il faut simplement fouiller dans la sdk Androïd. Chercher et récupérer le fichiers :

  • progress_horizontal.xml

Le copier dans le répertoire res/drawable de votre projet.

Le modifier

Editer le contenu du fichier pour modifier les valeurs des balises gradient suivantes :

  • @android:id/background
  • @android:id/secondaryProgress (si vous avez besoin d’afficher une deuxième zone de progression dans la même barre, à la manière d’un tampon de chargement dans un logiciel de visualisation de vidéo par exemple).
  • @android:id/progress

L’intégrer au projet

Il suffit maintenant de déclarer dans notre fichier de layout que nous utilisons ce fichier là pour nos barres de progression (attribut android:progressDrawable= »@drawable/progress_horizontal ») :

<ProgressBar android:id="@+id/progressBar1" style="?android:progressBarStyleHorizontal" android:minHeight="14dip" android:gravity="center_horizontal|center_vertical" android:progressDrawable="@drawable/progress_horizontal" android:maxHeight="14dip"</ProgressBar>

Changer l’épaisseur

L’épaisseur se change avec les attributs xml suivants, exprimés en dip (Density-independent Pixels), voir cet excellent post résumant les unités de mesure sur Androïd :

  • android:maxHeight
  • android:minHeight

Et voilà, ce n’est pas bien compliqué mais cela illustre une façon de modifier le comportement natif des éléments d’interface sous Androïd.

Petite mise à jour de classfinder

Je viens de mettre à jour classfinder pour y intégrer hsqldb. En effet, je ne trouvais pas la sauvegarde des données sous forme d’un objet sérialisé très élégante ;).
Maintenant un répertoire data est créé à la volée à côté du Jar, contenant tout ce dont à besoin hsqldb.
Les commandes sont les mêmes :
java -jar classfinder.jar -index chemin du répertoire à indexer
java -jar classfinder.jar -search nom de la classe

Note : il est maintenant possible de rechercher une classe en utilisant les jokers sql (% et _).

Pour télécharger : classfinder.jar et classfinder.zip (le projet eclipse).

A la recherche des jar manquants

Pour le boulot et pour le plaisir je suis régulièrement à la recherche de librairies Java. Soit parce que je reprends du vieux code, soit parce que je copie/colle des snippets à droite ou à gauche.

S’il est facile de retrouver des Jars open sources à l’aide de Google, c’est souvent plus délicat lorsqu’il s’agit de bibliothèques propriétaires (c’est souvent la cas au boulot car nous utilisons de nombreux frameworks non libres).
Le dernier exemple en date, je me suis retrouvé à chercher une classe bien précise. Je connaissais son package et son nom, mais le framework cible contenait des dizaines de Jars. Ne souhaitant pas polluer mon développement, ni notre dépôt Maven je ne me voyais pas tout mettre dans mon pom… Au petit bonheur la chance…
D’habitude j’utilise la recherche de mon OS ou un éditeur de texte capable de faire des recherches sur des fichiers binaires, mais c’est généralement une opération plutôt fastidieuse. Je me suis alors lancé dans l’écriture d’un petit utilitaire permettant de chercher dans des répertoires pour interroger tous les Jars trouvées. Cette recherche aveugle stocke le nom des Jars, les packages et les classes qu’ils contiennent. Pour finalement créer un fichier sérialisant les résultats trouvés. Ce qui me permet d’éviter de me taper le parcours des répertoires à chaque fois. Le résultat, cet « index » est bien évidement mis à jour à chaque nouvelle recherche, de façon à constituer petit à petit une « base » des classes disponibles dans mes environnements de développement.
Une deuxième fonction permet de rechercher une classe précise dans cet « index ». Si la classe est trouvée, le nom du package s’affiche.
Rudimentaire, mais cela me rend déjà des services 🙂

En en parlant autour de moi je me suis rendu compte que je n’étais pas le seul à chercher régulièrement des Jars.
Si vous rencontrez ce même besoin, vous trouverez les sources de ce mini projet à la fin ce poste… Ce n’est pas grand chose, quelques lignes de Java et un mvn package. Je n’ai même pas pris la peine de commenter le code, mais si cela peu dépanner.

Edit : voir maintenant ce post, Petite mise à jour de classfinder

Projet eclipse : http://www.kaerith.fr/download/classfinder.zip
Jar : http://www.kaerith.fr/download/classfinder.jar

java -jar classfinder.jar -index chemin du répertoire à indexer
java -jar classfinder.jar -search nom de la classe.class

Notes :

  • le nom de la classe est sensible à la casse.
  • le jar actuel nécessite java 1.6
  • si vous souhaiter enrichir au fur et à mesure votre index, n’oubliez pas de conserver à côté du jar le fichier map.ser

Lady Java kyrics

[Intro]
Ga Ga a a aaaa
Ja Ja Java Java
Ga Ga u le le le
Ja Ja Java Java soul
La La u a a aaaa
Ja Ja Java Java
Ga ga u le le le
Ja Ja Java Java soul

I wanna program like they do at Oracle
Let you feel my HotSpot, let you through my firewalls
I’m object oriented and I’m ready to Browse
So call me to my house and I will let you click my mouse

You can download me anywhere
You can get me for free

[Priedainis]
Java soul, Java soul
JAVA SOUL
Java soul, Java soul
Java Java Java
Java soul your PC hundredmillion times
Ja Ja Java soul, all nigth
Ja Ja Ja Ja Ja Ja Java soul
Ja Ja Ja Ja Ja JA Java soul
Java soul

If you say Voulez.vous(coucher).avec(moi);
I’m up for it if you can write it in Java
From software application to web application
My booty shakes that it’s been just-in-time compilation

Some people prefer other languages
And that’s OK if you’re retarded, I guess
They can go home with all their .NET mates
And jerk off to a picture of William Henry Gates

[Priedainis]

Java song, sympa :)

VLCJ (1)

Une alternative sans doute viable pour la gestion des webcams avec Java… VLCJ : http://code.google.com/p/vlcj/

Je teste ce pilotage de VLC via Java en ce moment et cela me semble prometteur. La compatibilité windows et gnu/linux est un sérieux plus.
Peut-être une suite à SecureCam 😉

La Javadoc est minimaliste, mais c’est mieux que rien.

SCALA premiers pas (1)

En vieux routard du java je ne pouvais pas passer à côté de groovy ou de scala.  Autant groovy n’a pas déclenché ma curiosité, autant je suis curieux des apports de SCALA.

Étant sensibilisé aux problématiques XML, de part mon travail, je commence par essayer de comprendre les capacités de SCALA à manipuler ce format.

Je dois avouer ne pas être déçut… Même grandement impressionné comme un marmot devant un magicien… Le bout de code suivant :

val tweet =
&lt;div id="feedTitle"&gt;
&lt;a id="feedTitleLink"&gt;
&lt;img id="feedTitleImage" /&gt;
&lt;/a&gt;
&lt;div id="feedTitleContainer"&gt;
&lt;h1 id="feedTitleText"&gt;Twitter / kaerith&lt;/h1&gt;
&lt;h2 id="feedSubtitleText"&gt;Twitter updates from kaerith /
kaerith.&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;;

Suffit pour déclarer un objet xml en mémoire…

Afficher la valeur de H1 ? Rien de plus simple :

val c2 = tweet \\ "h1"
println (c2.text)

Utiliser Nio (1) – la copie de fichiers

Premier post traitant d’une possible longue série décrivant mes expérimentations autour du package java.nio.

Mon expérience me montre que le package java.nio est assez peu utilisé, souvent par méconnaissance. NIO étant réputé plus rapide que IO concernant la manipulation de gros fichiers, je vais tenter d’en faire l’expérience en Java SUN 1.6.

Première étape : la copie d’un fichier de 16.5 mo d’un endroit du filesystem vers un autre.

Version classique java.io :

 /**
 
* copy file to new target. If new target doesn't exist, it ll be created.
 
*
 
* @param source
 
*            sourceFile
 
* @param target
 
*            target file
 
* @throws IOException
 
*             exception
 
*/
 
public static void copyFile(final File source, final File target)
 
throws IOException {
 
FileInputStream fis = null;
 
FileOutputStream fos = null;
 
try {
 
if (!target.exists()) {
 
target.createNewFile();
 
}
 
fis = new java.io.FileInputStream(source);
 
fos = new java.io.FileOutputStream(target);
 
final byte buffer[] = new byte[256 * 1024];  // 256Ko
 
int nbLecture;
 
while ((nbLecture = fis.read(buffer)) != -1) {
 
fos.write(buffer, 0, nbLecture);
 
}
 
} finally {
 
fis.close();
 
fos.close();
 
}
 
}

Version java.nio :

/**
 
* copy file to new target. If new target doesn't exists, it ll be created.
 
*
 
* @param source
 
*            sourceFile
 
* @param target
 
*            target file
 
* @throws IOException
 
*             exception
 
*/
 
public static void copyFile(final File source, final File target)
 
throws IOException {
 
if (!target.exists()) {
 
target.createNewFile();
 
}
 
FileChannel fileChannel = null;
 
FileChannel destination = null;
 
try {
 
fileChannel = new FileInputStream(source).getChannel();
 
destination = new FileOutputStream(target).getChannel();
 
destination.transferFrom(fileChannel, 0, fileChannel.size());
 
} finally {
 
if (fileChannel != null) {
 
fileChannel.close();
 
}
 
if (destination != null) {
 
destination.close();
 
}
 
}
 
}

Performances du disque dur

Performance Specifications

Rotational Speed 7,200 RPM (nominal)

Buffer Size 16 MB

Average Latency 5.50 ms (nominal)

Seek Times

Read Seek Time 12.0 ms

Track-To-Track Seek Time 2.0 ms (average)

Transfer Rates

Buffer To Host (Serial ATA) 3 Gb/s (Max)

Résultats :

A suivre…

Liens :

http://stackoverflow.com/questions/1605332/java-nio-filechannel-versus-fileoutputstream-performance-usefulness

http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/FileChannel.html#transferTo(long,%20long,%20java.nio.channels.WritableByteChannel)

Video surveillance en Java

L’objectif de ce mini-projet est la manipulation d’images 2D en java, en abordant par la même occasion différents algorithmes de détection de mouvement (motion detection).

Cahier des charges simplifié :

1.fonctionne sous GNU/linux Ubuntu
2.upload des images d’infraction par ftp
3.ajout facile de différents algo de motion detection en respectant simplement une interface Java.

Java ne semble pas être le langage idéal pour la video surveillance, la lenteur des opérations de traitement d’images risquant d’altérer l’ensemble du programme. Qu’en est-il vraiment ?

Ubuntu

Après quelques heures de recherches et d’essais, il me semble que JMF n’est pas le bon candidat. Trop obsolète.

Je me suis donc tourné vers un projet open source nommé : v4l4j.

Installation sans soucis sur mon fixe en ubuntu 8.10 et mon umpc en ubuntu 9.04.
Upload des images d’infraction via FTP

Je me suis inspiré du projet timcam. Comme lui j’utilise les sources de jFtp de Bea Petrovicova. L’objectif étant la découverte d’algo de détection de mouvement et pas FTP en soit.
Ajout facile de différents algo de motion detection en respectant simplement une interface Java

package kaerith.securecam.movedetector;

import java.awt.image.BufferedImage;

public interface IMotionDetector {

/**

* Alerte en fonction des 2 imges en parametre

* @param oldImage image de référence

* @param currentImage image actuelle

* @return boolean l’alerte est déclanchée

*/

public boolean bMoveAlert(BufferedImage oldImage, BufferedImage currentImage);

/**

* Accessor pour le nom du detecteur

* @return nom du detecteur

*/

public String getName();

}

Algorithme moyenne des pixels

Cet algorithme, qui s’est au final révélé fort peu intéressant fait la moyenne pour chaque image des différentes couleurs rouge, vert et bleu des pixels.

Pour cela on récupère dans chaque image tous les pixels :

PixelGrabber grabber = new PixelGrabber(image, 0, 0, -1, -1, false);

int[] data = (int[]) grabber.getPixels();

Puis, pixel par pixel on récupère sa valeur R, puis G puis B :

Color c = new Color(pixels[i]);

blue = blue + c.getBlue();

red = red + c.getRed();

green = green + c.getGreen();

Il ne reste plus qu’a faire une moyenne, en ajoutant ou non un certain degré de tolérance.

Algorithme soustraction simple


Cet algorithme pourtant plus simple donne de meilleurs résultats que le précédant, du moins tant que la luminosité ne change pas trop vite.

Son principe est simple : récupérer les valeurs des différents pixels de chaque images et les soustraire un à un. La encore en se laissant une tolérance paramétrable.

Pour récupérer un tableau de toutes valeurs de pixels d’un image :

int[] BufferedImage.getRGB(int x, int y)

Puis soustraire :

int[] tImgRef = imgRef.getRGB(0, 0, w, h, null, 0, w);

int[] tImgNew = imgNew.getRGB(0, 0, w, h, null, 0, w);

int[] tRet = new int[tImgRef.length];

for(int i = 0; i < tRet.length; i++) {

int diff = tImgNew[i] – tImgRef[i];

if( diff >= tolerance) {

nbRet++;

}

}

Variante : transformer les images en niveaux de gris, afin d’atténuer légèrement les problèmes de fausses détection à cause des changements de luminosité.

Algorithme soustractions multiple


La soustraction de deux images montre elle aussi rapidement ses limites en cas de brusque changement de luminosité.

Comment limiter au maximum l’influence de la luminosité ?

Au cours de différents essais, j ‘ai pu me rendre compte qu’il est très improbable que la luminosité chute d’un seul coup de façon importante. La nuit ne tombe pas si vite, pas vrai ? A l’inverse, si entre 2 images la luminosité à énormément variée, c’est certainement parce que quelqu’un est passé entre une source lumineuse et la caméra. Dans ce dernier cas, lever une alerte reste légitime.

Par contre, en condition de faible variation de luminosité il est fort probable qu’une petite zone de l’image changeant fortement sera susceptible de lever une alerte.

L’algorithme de découpage puis soustraction est une amélioration de celui de simple soustraction. Il permet de modérer les alertes non seulement sur les écarts entre les pixels de deux images mais aussi sur le nombre de zones modifiées.

Le principe est simple, les 2 images à comparer sont découpées en carrés. Chaque carré est soustrait de son supposé jumeaux, la tolérance de soustraction s’appliquant là aussi.
Pour chaque carré différent un compteur est incrémenté ; la position du carré est mémorisée.
Dès que tous les carrés ont été comparés, si le nombre de carrés différent dépasse le seuil fixé, l’alerte est donnée.

Les sources de Meduse 0.1 (alias SecureCam).

Prochaine version :
– gestion de plusieurs webcam

Haut de Page