From 51f0610147218ee72da9322ee9c10424f33a4227 Mon Sep 17 00:00:00 2001 From: Ray Chen Date: Thu, 3 Nov 2011 17:51:38 +0800 Subject: Fix 5481444 Face clustering should use PWA profile shot instead of random photo Change-Id: Ie4e3f9ae19431ab5b36d216cd7f4c626de503bbf --- src/com/android/gallery3d/data/ClusterAlbum.java | 10 ++ .../android/gallery3d/data/ClusterAlbumSet.java | 1 + src/com/android/gallery3d/data/Clustering.java | 3 + src/com/android/gallery3d/data/Face.java | 36 +++++-- src/com/android/gallery3d/data/FaceClustering.java | 105 +++++++++++++++------ src/com/android/gallery3d/data/LocalImage.java | 3 - src/com/android/gallery3d/data/MediaItem.java | 4 + 7 files changed, 122 insertions(+), 40 deletions(-) (limited to 'src/com/android/gallery3d/data') diff --git a/src/com/android/gallery3d/data/ClusterAlbum.java b/src/com/android/gallery3d/data/ClusterAlbum.java index 32f902301..569e5a4b3 100644 --- a/src/com/android/gallery3d/data/ClusterAlbum.java +++ b/src/com/android/gallery3d/data/ClusterAlbum.java @@ -24,6 +24,7 @@ public class ClusterAlbum extends MediaSet implements ContentListener { private String mName = ""; private DataManager mDataManager; private MediaSet mClusterAlbumSet; + private MediaItem mCover; public ClusterAlbum(Path path, DataManager dataManager, MediaSet clusterAlbumSet) { @@ -33,6 +34,15 @@ public class ClusterAlbum extends MediaSet implements ContentListener { mClusterAlbumSet.addContentListener(this); } + public void setCoverMediaItem(MediaItem cover) { + mCover = cover; + } + + @Override + public MediaItem getCoverMediaItem() { + return mCover != null ? mCover : super.getCoverMediaItem(); + } + void setMediaItems(ArrayList paths) { mPaths = paths; } diff --git a/src/com/android/gallery3d/data/ClusterAlbumSet.java b/src/com/android/gallery3d/data/ClusterAlbumSet.java index 5b0569a67..16501c22b 100644 --- a/src/com/android/gallery3d/data/ClusterAlbumSet.java +++ b/src/com/android/gallery3d/data/ClusterAlbumSet.java @@ -117,6 +117,7 @@ public class ClusterAlbumSet extends MediaSet implements ContentListener { } album.setMediaItems(clustering.getCluster(i)); album.setName(childName); + album.setCoverMediaItem(clustering.getClusterCover(i)); mAlbums.add(album); } } diff --git a/src/com/android/gallery3d/data/Clustering.java b/src/com/android/gallery3d/data/Clustering.java index 542dda27f..4072bf57b 100644 --- a/src/com/android/gallery3d/data/Clustering.java +++ b/src/com/android/gallery3d/data/Clustering.java @@ -23,4 +23,7 @@ public abstract class Clustering { public abstract int getNumberOfClusters(); public abstract ArrayList getCluster(int index); public abstract String getClusterName(int index); + public MediaItem getClusterCover(int index) { + return null; + } } diff --git a/src/com/android/gallery3d/data/Face.java b/src/com/android/gallery3d/data/Face.java index cc1a2d3dc..c5fd131ae 100644 --- a/src/com/android/gallery3d/data/Face.java +++ b/src/com/android/gallery3d/data/Face.java @@ -16,16 +16,41 @@ package com.android.gallery3d.data; +import android.graphics.Rect; + import com.android.gallery3d.common.Utils; +import java.util.StringTokenizer; + public class Face implements Comparable { private String mName; private String mPersonId; + private Rect mPosition; - public Face(String name, String personId) { + public Face(String name, String personId, String rect) { mName = name; mPersonId = personId; - Utils.assertTrue(mName != null && mPersonId != null); + Utils.assertTrue(mName != null && mPersonId != null && rect != null); + StringTokenizer tokenizer = new StringTokenizer(rect); + mPosition = new Rect(); + while (tokenizer.hasMoreElements()) { + mPosition.left = Integer.parseInt(tokenizer.nextToken()); + mPosition.top = Integer.parseInt(tokenizer.nextToken()); + mPosition.right = Integer.parseInt(tokenizer.nextToken()); + mPosition.bottom = Integer.parseInt(tokenizer.nextToken()); + } + } + + public Rect getPosition() { + return mPosition; + } + + public int getWidth() { + return mPosition.right - mPosition.left; + } + + public int getHeight() { + return mPosition.bottom - mPosition.top; } public String getName() { @@ -45,12 +70,7 @@ public class Face implements Comparable { return false; } - @Override - public int hashCode() { - return mPersonId.hashCode(); - } - public int compareTo(Face another) { - return mPersonId.compareTo(another.mPersonId); + return mName.compareTo(another.mName); } } diff --git a/src/com/android/gallery3d/data/FaceClustering.java b/src/com/android/gallery3d/data/FaceClustering.java index 6ed73b560..126286c34 100644 --- a/src/com/android/gallery3d/data/FaceClustering.java +++ b/src/com/android/gallery3d/data/FaceClustering.java @@ -16,79 +16,126 @@ package com.android.gallery3d.data; -import com.android.gallery3d.R; - import android.content.Context; +import android.graphics.Rect; + +import com.android.gallery3d.R; +import com.android.gallery3d.picasasource.PicasaSource; import java.util.ArrayList; -import java.util.Map; import java.util.TreeMap; public class FaceClustering extends Clustering { @SuppressWarnings("unused") private static final String TAG = "FaceClustering"; - private ArrayList> mClusters; - private String[] mNames; + private FaceCluster[] mClusters; private String mUntaggedString; + private Context mContext; + + private class FaceCluster { + ArrayList mPaths = new ArrayList(); + String mName; + MediaItem mCoverItem; + Rect mCoverRegion; + int mCoverFaceIndex; + + public FaceCluster(String name) { + mName = name; + } + + public void add(MediaItem item, int faceIndex) { + Path path = item.getPath(); + mPaths.add(path); + Face[] faces = item.getFaces(); + if (faces != null) { + Face face = faces[faceIndex]; + if (mCoverItem == null) { + mCoverItem = item; + mCoverRegion = face.getPosition(); + mCoverFaceIndex = faceIndex; + } else { + Rect region = face.getPosition(); + if (mCoverRegion.width() < region.width() && + mCoverRegion.height() < region.height()) { + mCoverItem = item; + mCoverRegion = face.getPosition(); + mCoverFaceIndex = faceIndex; + } + } + } + } + + public int size() { + return mPaths.size(); + } + + public MediaItem getCover() { + if (mCoverItem != null) { + if (PicasaSource.isPicasaImage(mCoverItem)) { + return PicasaSource.getFaceItem(mContext, mCoverItem, mCoverFaceIndex); + } else { + return mCoverItem; + } + } + return null; + } + } public FaceClustering(Context context) { mUntaggedString = context.getResources().getString(R.string.untagged); + mContext = context; } @Override public void run(MediaSet baseSet) { - final TreeMap> map = - new TreeMap>(); - final ArrayList untagged = new ArrayList(); + final TreeMap map = + new TreeMap(); + final FaceCluster untagged = new FaceCluster(mUntaggedString); baseSet.enumerateTotalMediaItems(new MediaSet.ItemConsumer() { public void consume(int index, MediaItem item) { - Path path = item.getPath(); - Face[] faces = item.getFaces(); if (faces == null || faces.length == 0) { - untagged.add(path); + untagged.add(item, -1); return; } for (int j = 0; j < faces.length; j++) { - Face key = faces[j]; - ArrayList list = map.get(key); - if (list == null) { - list = new ArrayList(); - map.put(key, list); + Face face = faces[j]; + FaceCluster cluster = map.get(face); + if (cluster == null) { + cluster = new FaceCluster(face.getName()); + map.put(face, cluster); } - list.add(path); + cluster.add(item, j); } } }); int m = map.size(); - mClusters = new ArrayList>(); - mNames = new String[m + ((untagged.size() > 0) ? 1 : 0)]; - int i = 0; - for (Map.Entry> entry : map.entrySet()) { - mNames[i++] = entry.getKey().getName(); - mClusters.add(entry.getValue()); - } + mClusters = map.values().toArray(new FaceCluster[m + ((untagged.size() > 0) ? 1 : 0)]); if (untagged.size() > 0) { - mNames[i++] = mUntaggedString; - mClusters.add(untagged); + mClusters[m] = untagged; } } @Override public int getNumberOfClusters() { - return mClusters.size(); + return mClusters.length; } @Override public ArrayList getCluster(int index) { - return mClusters.get(index); + return mClusters[index].mPaths; } @Override public String getClusterName(int index) { - return mNames[index]; + return mClusters[index].mName; + } + + @Override + public MediaItem getClusterCover(int index) { + return mClusters[index].getCover(); } } diff --git a/src/com/android/gallery3d/data/LocalImage.java b/src/com/android/gallery3d/data/LocalImage.java index e70b2eeef..fa3ece3b6 100644 --- a/src/com/android/gallery3d/data/LocalImage.java +++ b/src/com/android/gallery3d/data/LocalImage.java @@ -40,9 +40,6 @@ import java.io.IOException; // LocalImage represents an image in the local storage. public class LocalImage extends LocalMediaItem { - private static final int THUMBNAIL_TARGET_SIZE = 640; - private static final int MICROTHUMBNAIL_TARGET_SIZE = 200; - private static final String TAG = "LocalImage"; static final Path ITEM_PATH = Path.fromString("/local/image/item"); diff --git a/src/com/android/gallery3d/data/MediaItem.java b/src/com/android/gallery3d/data/MediaItem.java index a0c6d8c9e..b34a8c8a5 100644 --- a/src/com/android/gallery3d/data/MediaItem.java +++ b/src/com/android/gallery3d/data/MediaItem.java @@ -28,6 +28,10 @@ public abstract class MediaItem extends MediaObject { public static final int TYPE_THUMBNAIL = 1; public static final int TYPE_MICROTHUMBNAIL = 2; + public static final int THUMBNAIL_TARGET_SIZE = 640; + public static final int MICROTHUMBNAIL_TARGET_SIZE = 200; + public static final int CACHED_IMAGE_QUALITY = 95; + public static final int IMAGE_READY = 0; public static final int IMAGE_WAIT = 1; public static final int IMAGE_ERROR = -1; -- cgit v1.2.3