Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
7
Merge Requests
7
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Jérome Perrin
erp5
Commits
cd5cb546
Commit
cd5cb546
authored
Feb 01, 2024
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
safeimage: py3
parent
e75c17fd
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
41 additions
and
46 deletions
+41
-46
bt5/erp5_safeimage/ExtensionTemplateItem/portal_components/extension.erp5.ERP5ZoomifyImage.py
...Item/portal_components/extension.erp5.ERP5ZoomifyImage.py
+22
-25
bt5/erp5_safeimage/TestTemplateItem/portal_components/test.erp5.testSafeImage.py
...TemplateItem/portal_components/test.erp5.testSafeImage.py
+19
-21
No files found.
bt5/erp5_safeimage/ExtensionTemplateItem/portal_components/extension.erp5.ERP5ZoomifyImage.py
View file @
cd5cb546
...
...
@@ -16,9 +16,8 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from
__future__
import
print_function
import
io
import
os
,
sys
,
shutil
,
tempfile
from
six.moves
import
cStringIO
as
StringIO
from
zLOG
import
LOG
,
ERROR
,
INFO
,
WARNING
from
OFS.Image
import
File
,
Image
import
os
,
transaction
...
...
@@ -44,7 +43,7 @@ class ZoomifyBase:
_v_tileGroupMappings
=
{}
qualitySetting
=
80
tileSize
=
256
my_file
=
String
IO
()
my_file
=
io
.
Bytes
IO
()
def
openImage
(
self
):
""" load the image data """
...
...
@@ -62,15 +61,15 @@ class ZoomifyBase:
width
,
height
=
(
self
.
originalWidth
,
self
.
originalHeight
)
self
.
_v_scaleInfo
=
[(
width
,
height
)]
while
(
width
>
self
.
tileSize
)
or
(
height
>
self
.
tileSize
):
width
,
height
=
(
width
/
2
,
height
/
2
)
width
,
height
=
(
width
/
/
2
,
height
/
/
2
)
self
.
_v_scaleInfo
.
insert
(
0
,
(
width
,
height
))
totalTiles
=
0
tier
,
rows
,
columns
=
(
0
,
0
,
0
)
for
tierInfo
in
self
.
_v_scaleInfo
:
rows
=
height
/
self
.
tileSize
rows
=
height
//
self
.
tileSize
if
height
%
self
.
tileSize
>
0
:
rows
+=
1
columns
=
width
/
self
.
tileSize
columns
=
width
//
self
.
tileSize
if
width
%
self
.
tileSize
>
0
:
columns
+=
1
totalTiles
+=
rows
*
columns
...
...
@@ -87,7 +86,7 @@ class ZoomifyBase:
width
,
height
=
(
self
.
originalWidth
,
self
.
originalHeight
)
self
.
_v_scaleInfo
=
[(
width
,
height
)]
while
(
width
>
self
.
tileSize
)
or
(
height
>
self
.
tileSize
):
width
,
height
=
(
width
/
2
,
height
/
2
)
width
,
height
=
(
width
/
/
2
,
height
/
/
2
)
self
.
_v_scaleInfo
.
insert
(
0
,
(
width
,
height
))
# tile and tile group information
self
.
preProcess
()
...
...
@@ -146,7 +145,7 @@ class ZoomifyBase:
xmlOutput
=
'<IMAGE_PROPERTIES WIDTH="%s" HEIGHT="%s" NUMTILES="%s" NUMIMAGES="1" VERSION="1.8" TILESIZE="%s" />'
xmlOutput
=
xmlOutput
%
(
str
(
self
.
originalWidth
),
str
(
self
.
originalHeight
),
str
(
numberOfTiles
),
str
(
self
.
tileSize
))
return
xmlOutput
return
xmlOutput
.
encode
()
def
saveXMLOutput
(
self
):
""" save xml metadata about the tiles """
...
...
@@ -176,15 +175,14 @@ class ZoomifyBase:
lr_y
=
ul_y
+
self
.
tileSize
else
:
lr_y
=
self
.
originalHeight
print
(
"Going to open image"
)
imageRow
=
image
.
crop
([
0
,
ul_y
,
self
.
originalWidth
,
lr_y
])
saveFilename
=
root
+
str
(
tier
)
+
'-'
+
str
(
row
)
+
ext
if
imageRow
.
mode
!=
'RGB'
:
imageRow
=
imageRow
.
convert
(
'RGB'
)
imageRow
.
save
(
os
.
path
.
join
(
tempfile
.
gettempdir
(),
saveFilename
),
'JPEG'
,
quality
=
100
)
print
(
"os path exist : %r"
%
os
.
path
.
exists
(
os
.
path
.
join
(
tempfile
.
gettempdir
(),
saveFilename
))
)
# see https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#jpeg-saving
# for quality, Values above 95 should be avoided;
'JPEG'
,
quality
=
95
)
if
os
.
path
.
exists
(
os
.
path
.
join
(
tempfile
.
gettempdir
(),
saveFilename
)):
self
.
processRowImage
(
tier
=
tier
,
row
=
row
)
row
+=
1
...
...
@@ -192,9 +190,8 @@ class ZoomifyBase:
def
processRowImage
(
self
,
tier
=
0
,
row
=
0
):
""" for an image, create and save tiles """
print
(
'*** processing tier: '
+
str
(
tier
)
+
' row: '
+
str
(
row
))
tierWidth
,
tierHeight
=
self
.
_v_scaleInfo
[
tier
]
rowsForTier
=
tierHeight
/
self
.
tileSize
rowsForTier
=
tierHeight
//
self
.
tileSize
if
tierHeight
%
self
.
tileSize
>
0
:
rowsForTier
+=
1
root
,
ext
=
os
.
path
.
splitext
(
self
.
_v_imageFilename
)
...
...
@@ -261,7 +258,7 @@ class ZoomifyBase:
# a bug was discovered when a row was exactly 1 pixel in height
# this extra checking accounts for that
if
imageHeight
>
1
:
tempImage
=
imageRow
.
resize
((
imageWidth
/
2
,
imageHeight
/
2
),
tempImage
=
imageRow
.
resize
((
imageWidth
/
/
2
,
imageHeight
/
/
2
),
PIL_Image
.
ANTIALIAS
)
tempImage
.
save
(
os
.
path
.
join
(
tempfile
.
gettempdir
(),
root
+
str
(
tier
)
+
'-'
+
str
(
row
)
+
ext
))
...
...
@@ -269,9 +266,9 @@ class ZoomifyBase:
rowImage
=
None
if
tier
>
0
:
if
row
%
2
!=
0
:
self
.
processRowImage
(
tier
=
(
tier
-
1
),
row
=
((
row
-
1
)
/
2
))
self
.
processRowImage
(
tier
=
(
tier
-
1
),
row
=
((
row
-
1
)
/
/
2
))
elif
row
==
rowsForTier
-
1
:
self
.
processRowImage
(
tier
=
(
tier
-
1
),
row
=
(
row
/
2
))
self
.
processRowImage
(
tier
=
(
tier
-
1
),
row
=
(
row
/
/
2
))
def
ZoomifyProcess
(
self
,
imageNames
):
""" the method the client calls to generate zoomify metadata """
...
...
@@ -335,7 +332,7 @@ class ZoomifyZopeProcessor(ZoomifyBase):
def
openImage
(
self
):
""" load the image data """
return
PIL_Image
.
open
(
self
.
_v_imageObject
.
name
)
return
PIL_Image
.
open
(
self
.
_v_imageObject
)
def
createDefaultViewer
(
self
):
""" add the default Zoomify viewer to the Zoomify metadata """
...
...
@@ -411,7 +408,7 @@ class ZoomifyZopeProcessor(ZoomifyBase):
tileFileName
=
self
.
getTileFileName
(
scaleNumber
,
column
,
row
)
tileContainerName
=
self
.
getAssignedTileContainerName
(
tileFileName
=
tileFileName
)
tileImageData
=
String
IO
()
tileImageData
=
io
.
Bytes
IO
()
image
.
save
(
tileImageData
,
'JPEG'
,
quality
=
self
.
qualitySetting
)
tileImageData
.
seek
(
0
)
if
hasattr
(
self
.
_v_saveFolderObject
,
tileContainerName
):
...
...
@@ -529,7 +526,7 @@ class ERP5ZoomifyZopeProcessor(ZoomifyZopeProcessor):
param2
=
0
my_text
=
'%s %s %s %s %s %s
\
n
'
%
(
tile_group_id
,
tile_title
,
algorithm
,
param1
,
param2
,
num
)
self
.
my_file
.
write
(
my_text
)
self
.
my_file
.
write
(
my_text
.
encode
()
)
num
=
num
-
1
...
...
@@ -543,7 +540,7 @@ class ERP5ZoomifyZopeProcessor(ZoomifyZopeProcessor):
if
w
!=
0
and
h
!=
0
:
tile_group_id
=
self
.
getAssignedTileContainerName
()
tile_group
=
self
.
document
[
tile_group_id
]
tileImageData
=
String
IO
()
tileImageData
=
io
.
Bytes
IO
()
image
.
save
(
tileImageData
,
'JPEG'
,
quality
=
self
.
qualitySetting
)
tileImageData
.
seek
(
0
)
if
tile_group
is
None
:
...
...
@@ -556,11 +553,11 @@ class ERP5ZoomifyZopeProcessor(ZoomifyZopeProcessor):
def
saveXMLOutput
(
self
):
"""save the xml file"""
my_
string
=
String
IO
()
my_
string
.
write
(
self
.
getXMLOutput
())
my_
string
.
seek
(
0
)
my_
file
=
io
.
Bytes
IO
()
my_
file
.
write
(
self
.
getXMLOutput
())
my_
file
.
seek
(
0
)
self
.
document
.
newContent
(
portal_type
=
'Embedded File'
,
id
=
'ImageProperties.xml'
,
file
=
my_
string
,
id
=
'ImageProperties.xml'
,
file
=
my_
file
,
filename
=
'ImageProperties.xml'
)
return
...
...
bt5/erp5_safeimage/TestTemplateItem/portal_components/test.erp5.testSafeImage.py
View file @
cd5cb546
from
Products.ERP5Type.tests.ERP5TypeTestCase
import
ERP5TypeTestCase
import
transaction
from
io
import
File
IO
from
io
import
Bytes
IO
import
os
class
FileUpload
(
File
IO
):
class
FileUpload
(
Bytes
IO
):
"""Act as an uploaded file.
"""
__allow_access_to_unprotected_subobjects__
=
1
def
__init__
(
self
,
path
,
name
):
self
.
filename
=
name
super
(
FileUpload
,
self
).
__init__
(
path
)
with
open
(
path
,
'rb'
)
as
f
:
super
(
FileUpload
,
self
).
__init__
(
f
.
read
())
self
.
headers
=
{}
def
makeFilePath
(
name
):
#return os.path.join(os.path.dirname(__file__), 'tmp', name)
return
name
def
makeFileUpload
(
name
,
as_name
=
None
):
if
as_name
is
None
:
as_name
=
name
path
=
makeFilePath
(
name
)
return
FileUpload
(
path
,
as_name
)
class
TestSafeImage
(
ERP5TypeTestCase
):
def
afterSetUp
(
self
):
portal
=
self
.
getPortalObject
()
...
...
@@ -38,14 +29,21 @@ class TestSafeImage(ERP5TypeTestCase):
transaction
.
commit
()
self
.
tic
()
def
makeFileUpload
(
self
,
name
,
as_name
=
None
):
if
as_name
is
None
:
as_name
=
name
fu
=
FileUpload
(
name
,
as_name
)
self
.
addCleanup
(
fu
.
close
)
return
fu
def
_createImage
(
self
):
portal
=
self
.
getPortalObject
()
image
=
portal
.
restrictedTraverse
(
'portal_skins/erp5_safeimage/img/image_unit_test.jpg'
)
path_image
=
"image_unit_test.jpg"
fd
=
os
.
open
(
path_image
,
os
.
O_CREAT
|
os
.
O_RDWR
)
os
.
write
(
fd
,
str
(
image
.
data
))
os
.
write
(
fd
,
bytes
(
image
.
data
))
os
.
close
(
fd
)
_image
=
makeFileUpload
(
path_image
)
_image
=
self
.
makeFileUpload
(
path_image
)
image
=
self
.
image_module
.
newContent
(
portal_type
=
'Image'
,
title
=
'testImage'
,
id
=
'testImage'
,
file
=
_image
,
filename
=
'testImage'
)
return
image
...
...
@@ -55,9 +53,9 @@ class TestSafeImage(ERP5TypeTestCase):
image
=
portal
.
restrictedTraverse
(
'portal_skins/erp5_safeimage/img/image_unit_test.jpg'
)
path_image
=
"image_unit_test.jpg"
fd
=
os
.
open
(
path_image
,
os
.
O_CREAT
|
os
.
O_RDWR
)
os
.
write
(
fd
,
str
(
image
.
data
))
os
.
write
(
fd
,
bytes
(
image
.
data
))
os
.
close
(
fd
)
tile_image
=
makeFileUpload
(
path_image
)
tile_image
=
self
.
makeFileUpload
(
path_image
)
tile
=
self
.
image_module
.
newContent
(
portal_type
=
'Image Tile'
,
title
=
'testTile'
,
id
=
'testTile'
,
file
=
tile_image
,
filename
=
'testTile'
)
return
tile
...
...
@@ -67,9 +65,9 @@ class TestSafeImage(ERP5TypeTestCase):
image
=
portal
.
restrictedTraverse
(
'portal_skins/erp5_safeimage/img/image_unit_test.jpg'
)
path_image
=
"image_unit_test.jpg"
fd
=
os
.
open
(
path_image
,
os
.
O_CREAT
|
os
.
O_RDWR
)
os
.
write
(
fd
,
str
(
image
.
data
))
os
.
write
(
fd
,
bytes
(
image
.
data
))
os
.
close
(
fd
)
tile_image_transformed
=
makeFileUpload
(
path_image
)
tile_image_transformed
=
self
.
makeFileUpload
(
path_image
)
tile_transformed
=
self
.
image_module
.
newContent
(
portal_type
=
'Image Tile Transformed'
,
title
=
'testTileTransformed'
,
id
=
'testTileTransformed'
,
file
=
tile_image_transformed
,
filename
=
'testTileTransformed'
)
...
...
@@ -97,7 +95,7 @@ class TestSafeImage(ERP5TypeTestCase):
self
.
assertNotEqual
(
tile
,
None
)
image_property
=
getattr
(
tile
,
"ImageProperties.xml"
,
None
)
self
.
assertEqual
(
image_property
.
getData
(),
"""<IMAGE_PROPERTIES WIDTH="660" HEIGHT="495" NUMTILES="9" NUMIMAGES="1" VERSION="1.8" TILESIZE="256" />"""
)
b
"""<IMAGE_PROPERTIES WIDTH="660" HEIGHT="495" NUMTILES="9" NUMIMAGES="1" VERSION="1.8" TILESIZE="256" />"""
)
self
.
assertNotEqual
(
image_property
,
None
)
self
.
assertEqual
(
"Embedded File"
,
image_property
.
getPortalType
())
image_group
=
getattr
(
tile
,
"TileGroup0"
,
None
)
...
...
@@ -127,7 +125,7 @@ class TestSafeImage(ERP5TypeTestCase):
self
.
assertNotEqual
(
tile_transformed
,
None
)
image_property
=
getattr
(
tile_transformed
,
"ImageProperties.xml"
,
None
)
self
.
assertEqual
(
image_property
.
getData
(),
"""<IMAGE_PROPERTIES WIDTH="660" HEIGHT="495" NUMTILES="9" NUMIMAGES="1" VERSION="1.8" TILESIZE="256" />"""
)
b
"""<IMAGE_PROPERTIES WIDTH="660" HEIGHT="495" NUMTILES="9" NUMIMAGES="1" VERSION="1.8" TILESIZE="256" />"""
)
self
.
assertNotEqual
(
image_property
,
None
)
self
.
assertEqual
(
"Embedded File"
,
image_property
.
getPortalType
())
image_transform
=
getattr
(
tile_transformed
,
"TransformFile.txt"
,
None
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment