Skip to content

Commit e690718

Browse files
Merge pull request #60 from jonathanrocher/fix/consistent_image_folder
Make the `ImageFolder` model consistent across stages
2 parents 6a9f636 + 47f7df1 commit e690718

26 files changed

Lines changed: 186 additions & 146 deletions

File tree

stage2.1_traited_script/traited_face_detect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
Array, cached_property, Dict, File, HasStrictTraits, List, Property
1616
)
1717

18-
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg"]
18+
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg", ".PNG", ".JPG", ".JPEG"]
1919

2020

2121
class ImageFile(HasStrictTraits):

stage3.0_first_views/traited_face_detect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
)
1616
from traitsui.api import Item, OKButton, View
1717

18-
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg"]
18+
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg", ".PNG", ".JPG", ".JPEG"]
1919

2020

2121
class ImageFile(HasStrictTraits):

stage3.1_first_views/traited_face_detect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# Local imports
1919
from ets_tutorial.util.mpl_figure_editor import MplFigureEditor
2020

21-
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg"]
21+
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg", ".PNG", ".JPG", ".JPEG"]
2222

2323

2424
class ImageFile(HasStrictTraits):

stage4.1_first_application/pycasa/model/image_file.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
Array, cached_property, Dict, File, HasStrictTraits, List, Property
1212
)
1313

14-
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg"]
14+
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg", ".PNG", ".JPG", ".JPEG"]
1515

1616

1717
class ImageFile(HasStrictTraits):

stage4.1_first_application/pycasa/ui/tasks/pycasa_task.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77

88
# Local imports
99
from .pycasa_browser_pane import PycasaBrowserPane
10-
from ...model.image_file import ImageFile
10+
from ...model.image_file import ImageFile, SUPPORTED_FORMATS
1111
from ..image_file_editor import ImageFileEditor
1212

13-
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg"]
14-
1513

1614
class PycasaTask(Task):
1715
# 'Task' traits -----------------------------------------------------------
@@ -52,4 +50,4 @@ def open_in_central_pane(self, filepath):
5250
obj = ImageFile(filepath=filepath)
5351
self.central_pane.edit(obj, factory=ImageFileEditor)
5452
else:
55-
print("Unsupported file format: {}".format(file_ext))
53+
print("Unsupported file format: '{}'".format(file_ext))
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Second real version of the pycasa ETS pyface application!
2-
Building on the application state 4.2, this version simply adds an editor and a
3-
view for a folder to be visualized.
2+
Building on the application state 4.1, this version adds a model and view for
3+
a folder of image files.

stage5.1_fuller_application/pycasa/model/image_file.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
Array, cached_property, Dict, File, HasStrictTraits, List, Property
1212
)
1313

14-
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg"]
14+
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg", ".PNG", ".JPG", ".JPEG"]
1515

1616

1717
class ImageFile(HasStrictTraits):
Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11

22
# General imports
33
import glob
4-
from os.path import expanduser, isdir, split
4+
from os.path import basename, expanduser, isdir
55

6+
import numpy as np
67
import pandas as pd
78

89
# ETS imports
@@ -11,9 +12,10 @@
1112
)
1213

1314
# Local imports
14-
from pycasa.model.image_file import ImageFile
15+
from pycasa.model.image_file import ImageFile, SUPPORTED_FORMATS
1516

16-
SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg", ".PNG", ".JPG", ".JPEG"]
17+
FILENAME_COL = "filename"
18+
NUM_FACE_COL = "Num. faces"
1719

1820

1921
class ImageFolder(HasStrictTraits):
@@ -23,23 +25,38 @@ class ImageFolder(HasStrictTraits):
2325

2426
images = List(Instance(ImageFile))
2527

28+
data = Instance(pd.DataFrame)
29+
2630
def __init__(self, **traits):
31+
# Don't forget this!
2732
super(ImageFolder, self).__init__(**traits)
2833
if not isdir(self.directory):
2934
msg = f"The provided directory isn't a real directory: " \
3035
f"{self.directory}"
3136
raise ValueError(msg)
37+
self.data = self._create_metadata_df()
3238

3339
@observe("directory")
34-
def _get_images(self, event):
40+
def _update_images(self, event):
3541
self.images = [
3642
ImageFile(filepath=file)
3743
for fmt in SUPPORTED_FORMATS
3844
for file in glob.glob(f"{self.directory}/*{fmt}")
3945
]
4046

41-
def create_metadata_df(self):
42-
return pd.DataFrame(
43-
[img.metadata for img in self.images],
44-
index=[split(img.filepath)[1] for img in self.images]
45-
)
47+
@observe("images.items")
48+
def _update_metadata(self, event):
49+
self.data = self._create_metadata_df()
50+
51+
def _create_metadata_df(self):
52+
if not self.images:
53+
return pd.DataFrame({FILENAME_COL: [], NUM_FACE_COL: []})
54+
return pd.DataFrame([
55+
{
56+
FILENAME_COL: basename(img.filepath),
57+
NUM_FACE_COL: np.nan,
58+
**img.metadata
59+
60+
}
61+
for img in self.images
62+
])

stage5.1_fuller_application/pycasa/model/tests/test_image_folder.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from os.path import dirname, join, split
22
import unittest
33

4-
from pycasa.model.image_folder import ImageFolder
4+
from pycasa.model.image_folder import FILENAME_COL, ImageFolder
55

66
import ets_tutorial
77

@@ -24,8 +24,8 @@ def test_filters_images(self):
2424
set(self.filenames)
2525
)
2626

27-
def test_create_metadata_df(self):
28-
df = self.img_folder.create_metadata_df()
29-
self.assertEqual(set(df.index), set(self.filenames))
27+
def test_data_correct(self):
28+
df = self.img_folder.data
29+
self.assertEqual(set(df[FILENAME_COL]), set(self.filenames))
3030
self.assertIn("ExifVersion", df)
3131
self.assertIn("ApertureValue", df)

stage5.1_fuller_application/pycasa/ui/image_folder_view.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
from traits.api import cached_property, Instance, Property
2-
from traitsui.api import Item, ModelView, View
1+
from traits.api import Instance
2+
from traitsui.api import (
3+
HGroup, Item, Label, ModelView, Spring, View
4+
)
35
from traitsui.ui_editors.data_frame_editor import DataFrameEditor
46

5-
from pycasa.model.image_folder import ImageFolder
7+
# Local imports
8+
from pycasa.model.image_folder import FILENAME_COL, ImageFolder, NUM_FACE_COL
69

7-
DISPLAYED_COLUMNS = [
10+
11+
DISPLAYED_COLUMNS = [FILENAME_COL, NUM_FACE_COL] + [
812
'ApertureValue', 'ExifVersion', 'Model', 'Make', 'LensModel', 'DateTime',
9-
'ShutterSpeedValue', 'XResolution', 'YResolution'
13+
'ShutterSpeedValue', 'ExposureTime', 'XResolution', 'YResolution',
14+
'Orientation', 'GPSInfo', 'DigitalZoomRatio', 'FocalLengthIn35mmFilm',
15+
'ISOSpeedRatings', 'SceneType'
1016
]
1117

1218

@@ -15,23 +21,23 @@ class ImageFolderView(ModelView):
1521
"""
1622
model = Instance(ImageFolder)
1723

18-
metadata_df = Property(depends_on="model.images.items")
19-
2024
view = View(
2125
Item('model.directory', style="readonly", show_label=False),
2226
Item(
23-
'metadata_df',
27+
'model.data',
2428
editor=DataFrameEditor(columns=DISPLAYED_COLUMNS),
2529
show_label=False,
26-
width=1200,
30+
visible_when="len(model.data) > 0",
31+
),
32+
HGroup(
33+
Spring(),
34+
Label("No images found. No data to show"),
35+
Spring(),
36+
visible_when="len(model.data) == 0",
2737
),
2838
resizable=True
2939
)
3040

31-
@cached_property
32-
def _get_metadata_df(self):
33-
return self.model.create_metadata_df()
34-
3541

3642
if __name__ == '__main__':
3743
from os.path import dirname, join

0 commit comments

Comments
 (0)