From 2c2242da3cebd2361bcf7bba7a12a14b00a776d2 Mon Sep 17 00:00:00 2001 From: Santiago Moscoso Date: Sun, 7 Sep 2025 09:58:14 -0700 Subject: [PATCH 1/2] Add support for `.bmp` and `.jpg` images. --- bcipy/core/symbols.py | 6 ++--- .../core/tests/resources/images/1x1_PLUS.bmp | Bin 0 -> 58 bytes .../core/tests/resources/images/1x1_PLUS.jpg | Bin 0 -> 518 bytes .../core/tests/resources/images/1x1_PLUS.png | Bin 0 -> 142 bytes bcipy/core/tests/resources/images/a_1x1.bmp | Bin 0 -> 58 bytes bcipy/core/tests/resources/images/b_1x1.jpg | Bin 0 -> 518 bytes bcipy/core/tests/resources/images/c_1x1.png | Bin 0 -> 142 bytes bcipy/core/tests/resources/images/text.txt | 1 + bcipy/core/tests/test_symbols.py | 23 +++++++++++++----- bcipy/display/paradigm/rsvp/display.py | 2 +- bcipy/parameters/parameters.json | 2 +- 11 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 bcipy/core/tests/resources/images/1x1_PLUS.bmp create mode 100644 bcipy/core/tests/resources/images/1x1_PLUS.jpg create mode 100644 bcipy/core/tests/resources/images/1x1_PLUS.png create mode 100644 bcipy/core/tests/resources/images/a_1x1.bmp create mode 100644 bcipy/core/tests/resources/images/b_1x1.jpg create mode 100644 bcipy/core/tests/resources/images/c_1x1.png create mode 100644 bcipy/core/tests/resources/images/text.txt diff --git a/bcipy/core/symbols.py b/bcipy/core/symbols.py index 1b642e4fe..2318073ab 100644 --- a/bcipy/core/symbols.py +++ b/bcipy/core/symbols.py @@ -32,12 +32,12 @@ def alphabet(parameters: Optional[Any] = None, include_path: bool = True, stimulus_array: List[str] = [] for stimulus_filename in sorted(os.listdir(path)): # PLUS.png is reserved for the fixation symbol - if stimulus_filename.endswith( - '.png') and not stimulus_filename.endswith('PLUS.png'): + root, ext = os.path.splitext(stimulus_filename) + if ext in [".png", ".bmp", ".jpg"] and not root.endswith("PLUS"): if include_path: img = os.path.join(path, stimulus_filename) else: - img = os.path.splitext(stimulus_filename)[0] + img = root stimulus_array.append(img) return stimulus_array diff --git a/bcipy/core/tests/resources/images/1x1_PLUS.bmp b/bcipy/core/tests/resources/images/1x1_PLUS.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b3ae134e961334e3cdae14499f5cb50fdd516118 GIT binary patch literal 58 lcmZ?rwPJt(Ga#h_#Eft(0hV9^lFE7z3>E+q|NsAI0032<1m*w$ literal 0 HcmV?d00001 diff --git a/bcipy/core/tests/resources/images/1x1_PLUS.jpg b/bcipy/core/tests/resources/images/1x1_PLUS.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d1d27bf7cfa448e32466b0758b71ab209176872f GIT binary patch literal 518 zcmb7@om_f%5zerZAXqX$n_ZQ$!W uDX~p}`wU2;hPnXp1inV}nl|DqK+SCXC=D5Z757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10g2&Uv iF@)oK@{j-j?HO4AG5x!9Ch|E@oWax8&t;ucLK6UWeI&yG literal 0 HcmV?d00001 diff --git a/bcipy/core/tests/resources/images/a_1x1.bmp b/bcipy/core/tests/resources/images/a_1x1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b3ae134e961334e3cdae14499f5cb50fdd516118 GIT binary patch literal 58 lcmZ?rwPJt(Ga#h_#Eft(0hV9^lFE7z3>E+q|NsAI0032<1m*w$ literal 0 HcmV?d00001 diff --git a/bcipy/core/tests/resources/images/b_1x1.jpg b/bcipy/core/tests/resources/images/b_1x1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d1d27bf7cfa448e32466b0758b71ab209176872f GIT binary patch literal 518 zcmb7@om_f%5zerZAXqX$n_ZQ$!W uDX~p}`wU2;hPnXp1inV}nl|DqK+SCXC=D5Z757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10g2&Uv iF@)oK@{j-j?HO4AG5x!9Ch|E@oWax8&t;ucLK6UWeI&yG literal 0 HcmV?d00001 diff --git a/bcipy/core/tests/resources/images/text.txt b/bcipy/core/tests/resources/images/text.txt new file mode 100644 index 000000000..7a98a964f --- /dev/null +++ b/bcipy/core/tests/resources/images/text.txt @@ -0,0 +1 @@ +Text file for testing only images are collected from the folder. \ No newline at end of file diff --git a/bcipy/core/tests/test_symbols.py b/bcipy/core/tests/test_symbols.py index f3cfce7a0..1eea4091a 100644 --- a/bcipy/core/tests/test_symbols.py +++ b/bcipy/core/tests/test_symbols.py @@ -17,15 +17,26 @@ def test_alphabet_text(self): '<', '_' ]) - def test_alphabet_images(self): + def test_alphabet_images_with_path(self): + path = 'bcipy/core/tests/resources/images/' parameters = {} parameters['is_txt_stim'] = False - parameters['path_to_presentation_images'] = ('bcipy/static/images/' - 'rsvp/') + parameters['path_to_presentation_images'] = path alp = alphabet(parameters) - self.assertNotEqual(alp, [ - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'V', 'Y', 'Z', '<', '_' + self.assertEqual(alp, [ + path + 'a_1x1.bmp', + path + 'b_1x1.jpg', + path + 'c_1x1.png' ]) + + def test_alphabet_images_without_path(self): + path = 'bcipy/core/tests/resources/images/' + parameters = {} + parameters['is_txt_stim'] = False + parameters['path_to_presentation_images'] = path + + alp = alphabet(parameters, include_path=False) + + self.assertEqual(alp, ['a_1x1', 'b_1x1', 'c_1x1']) diff --git a/bcipy/display/paradigm/rsvp/display.py b/bcipy/display/paradigm/rsvp/display.py index 2c075edad..b8aa6a276 100644 --- a/bcipy/display/paradigm/rsvp/display.py +++ b/bcipy/display/paradigm/rsvp/display.py @@ -319,7 +319,7 @@ def _generate_inquiry(self) -> List[Dict[str, Any]]: this_stimuli_size = (self.size_list_sti[idx] if self.size_list_sti else self.stimuli_height) - if stim.endswith('.png'): + if any([stim.endswith(ext) for ext in [".png", ".bmp", ".jpg"]]): current_stim['sti'] = self._create_stimulus( mode='image', height=this_stimuli_size, diff --git a/bcipy/parameters/parameters.json b/bcipy/parameters/parameters.json index 790225272..ccbb7fef0 100755 --- a/bcipy/parameters/parameters.json +++ b/bcipy/parameters/parameters.json @@ -267,7 +267,7 @@ "value": "bcipy/static/images/rsvp/", "section": "bci_config", "name": "Image Stimulus Folder", - "helpTip": "Specifies the location of image files to be used as stimuli (Text Stimuli On/Off must be set to ‘false’). This must be a directory ending with /.", + "helpTip": "Specifies the location of image files to be used as stimuli (Text Stimuli On/Off must be set to ‘false’). This must be a directory ending with /. Image files must have extension .bmp, .jpg, or .png. Files ending in PLUS.bmp, PLUS.jpg, or PLUS.png, are ignored as they are assumed to be fixation images.", "recommended": "", "editable": false, "type": "directorypath" From 6c9f2830a00c0bc654bbde4483cb0bdc7c089126 Mon Sep 17 00:00:00 2001 From: Santiago Moscoso Date: Tue, 9 Sep 2025 12:48:28 -0700 Subject: [PATCH 2/2] Add type annotation to parameters dictionary in TestAlphabet to fix warning from Codacy Static Code Analysis --- bcipy/core/tests/test_symbols.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bcipy/core/tests/test_symbols.py b/bcipy/core/tests/test_symbols.py index 1eea4091a..0c3dead80 100644 --- a/bcipy/core/tests/test_symbols.py +++ b/bcipy/core/tests/test_symbols.py @@ -1,7 +1,7 @@ import unittest from bcipy.core.symbols import alphabet - +from typing import Dict class TestAlphabet(unittest.TestCase): def test_alphabet_text(self): @@ -19,7 +19,7 @@ def test_alphabet_text(self): def test_alphabet_images_with_path(self): path = 'bcipy/core/tests/resources/images/' - parameters = {} + parameters: Dict[str, bool | str] = {} parameters['is_txt_stim'] = False parameters['path_to_presentation_images'] = path @@ -33,7 +33,7 @@ def test_alphabet_images_with_path(self): def test_alphabet_images_without_path(self): path = 'bcipy/core/tests/resources/images/' - parameters = {} + parameters: Dict[str, bool | str] = {} parameters['is_txt_stim'] = False parameters['path_to_presentation_images'] = path