shinestacker 1.4.0__py3-none-any.whl → 1.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of shinestacker might be problematic. Click here for more details.

@@ -2,8 +2,8 @@
2
2
  import math
3
3
  from abc import abstractmethod
4
4
  import numpy as np
5
- from PySide6.QtCore import Qt, QPointF, QTime, QPoint, Signal
6
- from PySide6.QtGui import QImage, QPainter, QColor, QBrush, QPen, QCursor
5
+ from PySide6.QtCore import Qt, QPointF, QTime, QPoint, Signal, QRectF
6
+ from PySide6.QtGui import QImage, QPainter, QColor, QBrush, QPen, QCursor, QPixmap
7
7
  from PySide6.QtWidgets import (
8
8
  QGraphicsEllipseItem, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem)
9
9
  from .. config.gui_constants import gui_constants
@@ -52,7 +52,6 @@ class ViewStrategy(LayerCollectionHandler):
52
52
  self.pinch_center_view = None
53
53
  self.pinch_center_scene = None
54
54
  self.pinch_start_scale = None
55
- self.last_scroll_pos = None
56
55
  self.scrolling = False
57
56
  self.dragging = False
58
57
  self.last_brush_pos = None
@@ -72,19 +71,19 @@ class ViewStrategy(LayerCollectionHandler):
72
71
  pass
73
72
 
74
73
  @abstractmethod
75
- def update_master_display(self):
74
+ def get_master_view(self):
76
75
  pass
77
76
 
78
77
  @abstractmethod
79
- def update_current_display(self):
78
+ def get_current_view(self):
80
79
  pass
81
80
 
82
81
  @abstractmethod
83
- def get_master_view(self):
82
+ def get_master_scene(self):
84
83
  pass
85
84
 
86
85
  @abstractmethod
87
- def get_master_scene(self):
86
+ def get_current_scene(self):
88
87
  pass
89
88
 
90
89
  @abstractmethod
@@ -103,12 +102,52 @@ class ViewStrategy(LayerCollectionHandler):
103
102
  def get_master_pixmap(self):
104
103
  pass
105
104
 
105
+ @abstractmethod
106
+ def get_current_pixmap(self):
107
+ pass
108
+
109
+ @abstractmethod
106
110
  def show_master(self):
107
111
  pass
108
112
 
113
+ @abstractmethod
109
114
  def show_current(self):
110
115
  pass
111
116
 
117
+ @abstractmethod
118
+ def arrange_images(self):
119
+ pass
120
+
121
+ def update_master_display(self):
122
+ if not self.empty():
123
+ master_qimage = self.numpy_to_qimage(self.master_layer())
124
+ if master_qimage:
125
+ pixmap = QPixmap.fromImage(master_qimage)
126
+ self.get_master_pixmap().setPixmap(pixmap)
127
+ self.get_master_scene().setSceneRect(QRectF(pixmap.rect()))
128
+ self.get_master_view().horizontalScrollBar().setValue(self.status.h_scroll)
129
+ self.get_master_view().verticalScrollBar().setValue(self.status.v_scroll)
130
+ self.arrange_images()
131
+
132
+ def update_current_display(self):
133
+ if not self.empty() and self.number_of_layers() > 0:
134
+ current_qimage = self.numpy_to_qimage(self.current_layer())
135
+ if current_qimage:
136
+ pixmap = QPixmap.fromImage(current_qimage)
137
+ self.get_current_pixmap().setPixmap(pixmap)
138
+ self.get_current_scene().setSceneRect(QRectF(pixmap.rect()))
139
+ self.get_current_view().horizontalScrollBar().setValue(self.status.h_scroll)
140
+ self.get_current_view().verticalScrollBar().setValue(self.status.v_scroll)
141
+ self.arrange_images()
142
+
143
+ def update_cursor_pen_width(self):
144
+ pen_width = gui_constants.BRUSH_LINE_WIDTH / self.zoom_factor()
145
+ if self.brush_cursor is not None:
146
+ master_pen = self.brush_cursor.pen()
147
+ master_pen.setWidthF(pen_width)
148
+ self.brush_cursor.setPen(master_pen)
149
+ return pen_width
150
+
112
151
  def set_allow_cursor_preview(self, state):
113
152
  self.allow_cursor_preview = state
114
153
 
@@ -154,10 +193,10 @@ class ViewStrategy(LayerCollectionHandler):
154
193
  return self.cursor_style
155
194
 
156
195
  def handle_key_press_event(self, _event):
157
- return
196
+ return True
158
197
 
159
198
  def handle_key_release_event(self, _event):
160
- return
199
+ return True
161
200
 
162
201
  def clear_image(self):
163
202
  for scene in self.get_scenes():
@@ -171,6 +210,11 @@ class ViewStrategy(LayerCollectionHandler):
171
210
  if self.brush_cursor:
172
211
  self.brush_cursor.hide()
173
212
 
213
+ def cleanup_brush_preview(self):
214
+ if self.brush_cursor:
215
+ self.brush_cursor.hide()
216
+ self.brush_preview.hide()
217
+
174
218
  def set_master_image_np(self, img):
175
219
  self.set_master_image(self.numpy_to_qimage(img))
176
220
 
@@ -201,9 +245,14 @@ class ViewStrategy(LayerCollectionHandler):
201
245
  return pixmap_item
202
246
 
203
247
  def refresh_display(self):
204
- self.update_brush_cursor()
205
248
  for scene in self.get_scenes():
206
249
  scene.update()
250
+ self.update_brush_cursor()
251
+
252
+ def set_max_min_scales(self, img_width, img_height):
253
+ self.set_min_scale(min(gui_constants.MIN_ZOOMED_IMG_WIDTH / img_width,
254
+ gui_constants.MIN_ZOOMED_IMG_HEIGHT / img_height))
255
+ self.set_max_scale(gui_constants.MAX_ZOOMED_IMG_PX_SIZE)
207
256
 
208
257
  def zoom_in(self):
209
258
  if self.empty():
@@ -218,6 +267,15 @@ class ViewStrategy(LayerCollectionHandler):
218
267
  self.set_zoom_factor(new_scale)
219
268
  master_view.centerOn(old_center)
220
269
  self.update_brush_cursor()
270
+ self.update_cursor_pen_width()
271
+
272
+ def apply_zoom(self):
273
+ if self.empty():
274
+ return
275
+ for view in self.get_views():
276
+ current_scale = view.transform().m11()
277
+ scale_factor = self.zoom_factor() / current_scale
278
+ view.scale(scale_factor, scale_factor)
221
279
 
222
280
  def zoom_out(self):
223
281
  if self.empty():
@@ -232,12 +290,12 @@ class ViewStrategy(LayerCollectionHandler):
232
290
  self.set_zoom_factor(new_scale)
233
291
  master_view.centerOn(old_center)
234
292
  self.update_brush_cursor()
293
+ self.update_cursor_pen_width()
235
294
 
236
295
  def reset_zoom(self):
237
296
  if self.empty():
238
297
  return
239
298
  self.pinch_start_scale = 1.0
240
- self.last_scroll_pos = QPointF()
241
299
  self.gesture_active = False
242
300
  self.pinch_center_view = None
243
301
  self.pinch_center_scene = None
@@ -249,6 +307,7 @@ class ViewStrategy(LayerCollectionHandler):
249
307
  view.resetTransform()
250
308
  view.scale(self.zoom_factor(), self.zoom_factor())
251
309
  self.update_brush_cursor()
310
+ self.update_cursor_pen_width()
252
311
 
253
312
  def actual_size(self):
254
313
  if self.empty():
@@ -258,6 +317,7 @@ class ViewStrategy(LayerCollectionHandler):
258
317
  view.resetTransform()
259
318
  view.scale(self.zoom_factor(), self.zoom_factor())
260
319
  self.update_brush_cursor()
320
+ self.update_cursor_pen_width()
261
321
 
262
322
  def setup_outline_style(self):
263
323
  self.brush_cursor.setPen(QPen(QColor(*gui_constants.BRUSH_COLORS['pen']),
@@ -278,17 +338,16 @@ class ViewStrategy(LayerCollectionHandler):
278
338
  if isinstance(item, QGraphicsEllipseItem) and item != self.brush_preview:
279
339
  scene.removeItem(item)
280
340
  pen = QPen(QColor(*gui_constants.BRUSH_COLORS['pen']), 1)
281
- brush = QBrush(QColor(*gui_constants.BRUSH_COLORS['cursor_inner']))
341
+ brush = Qt.NoBrush
282
342
  self.brush_cursor = scene.addEllipse(
283
343
  0, 0, self.brush.size, self.brush.size, pen, brush)
284
344
  self.brush_cursor.setZValue(1000)
285
345
  self.brush_cursor.hide()
286
346
 
287
347
  def update_brush_cursor(self):
288
- if self.empty():
289
- return
290
- if not self.brush_cursor or not self.isVisible():
348
+ if self.empty() or not self.brush_cursor or not self.isVisible():
291
349
  return
350
+ self.update_cursor_pen_width()
292
351
  master_view = self.get_master_view()
293
352
  mouse_pos = master_view.mapFromGlobal(QCursor.pos())
294
353
  if not master_view.rect().contains(mouse_pos):
@@ -299,19 +358,20 @@ class ViewStrategy(LayerCollectionHandler):
299
358
  radius = size / 2
300
359
  self.brush_cursor.setRect(scene_pos.x() - radius, scene_pos.y() - radius, size, size)
301
360
  allow_cursor_preview = self.display_manager.allow_cursor_preview()
302
- if self.cursor_style == 'preview' and allow_cursor_preview:
361
+ if self.cursor_style == 'preview':
303
362
  self.setup_outline_style()
304
- self.brush_cursor.hide()
305
- pos = QCursor.pos()
306
- if isinstance(pos, QPointF):
307
- scene_pos = pos
308
- else:
309
- cursor_pos = master_view.mapFromGlobal(pos)
310
- scene_pos = master_view.mapToScene(cursor_pos)
311
- self.brush_preview.update(scene_pos, int(size))
363
+ if allow_cursor_preview:
364
+ self.brush_cursor.hide()
365
+ pos = QCursor.pos()
366
+ if isinstance(pos, QPointF):
367
+ scene_pos = pos
368
+ else:
369
+ cursor_pos = master_view.mapFromGlobal(pos)
370
+ scene_pos = master_view.mapToScene(cursor_pos)
371
+ self.brush_preview.update(scene_pos, int(size))
312
372
  else:
313
373
  self.brush_preview.hide()
314
- if self.cursor_style == 'outline' or not allow_cursor_preview:
374
+ if self.cursor_style == 'outline':
315
375
  self.setup_outline_style()
316
376
  else:
317
377
  self.setup_simple_brush_style(scene_pos.x(), scene_pos.y(), radius)
@@ -354,41 +414,53 @@ class ViewStrategy(LayerCollectionHandler):
354
414
  def keyPressEvent(self, event):
355
415
  if self.empty():
356
416
  return
357
- master_view = self.get_master_view()
358
417
  if event.key() == Qt.Key_Space and not self.scrolling:
359
418
  self.space_pressed = True
360
- master_view.setCursor(Qt.OpenHandCursor)
419
+ self.get_master_view().setCursor(Qt.OpenHandCursor)
361
420
  if self.brush_cursor:
362
421
  self.brush_cursor.hide()
363
- self.handle_key_press_event(event)
364
- if event.key() == Qt.Key_Control and not self.scrolling:
365
- self.control_pressed = True
366
- super().keyPressEvent(event)
422
+ if self.handle_key_press_event(event):
423
+ if event.key() == Qt.Key_Control and not self.scrolling:
424
+ self.control_pressed = True
425
+ super().keyPressEvent(event)
367
426
 
368
427
  def keyReleaseEvent(self, event):
369
428
  if self.empty():
370
429
  return
371
- master_view = self.get_master_view()
372
430
  self.update_brush_cursor()
373
431
  if event.key() == Qt.Key_Space:
374
432
  self.space_pressed = False
375
433
  if not self.scrolling:
376
- master_view.setCursor(Qt.BlankCursor)
434
+ self.get_master_view().setCursor(Qt.BlankCursor)
377
435
  if self.brush_cursor:
378
436
  self.brush_cursor.show()
379
- self.handle_key_release_event(event)
380
- if event.key() == Qt.Key_Control:
381
- self.control_pressed = False
382
- super().keyReleaseEvent(event)
437
+ if self.handle_key_release_event(event):
438
+ if event.key() == Qt.Key_Control:
439
+ self.control_pressed = False
440
+ super().keyReleaseEvent(event)
383
441
 
384
442
  def leaveEvent(self, event):
385
- if not self.empty():
443
+ if self.empty():
444
+ self.setCursor(Qt.ArrowCursor)
445
+ else:
386
446
  self.get_master_view().setCursor(Qt.ArrowCursor)
387
447
  if self.brush_cursor:
388
448
  self.brush_cursor.hide()
389
449
  super().leaveEvent(event)
390
450
  # pylint: enable=C0103
391
451
 
452
+ def scroll_view(self, view, delta_x, delta_y):
453
+ view.horizontalScrollBar().setValue(
454
+ view.horizontalScrollBar().value() - delta_x)
455
+ view.verticalScrollBar().setValue(
456
+ view.verticalScrollBar().value() - delta_y)
457
+ self.status.set_scroll(view.horizontalScrollBar().value(),
458
+ view.verticalScrollBar().value())
459
+
460
+ def center_image(self, view):
461
+ view.horizontalScrollBar().setValue(self.status.h_scroll)
462
+ view.verticalScrollBar().setValue(self.status.v_scroll)
463
+
392
464
  def mouse_move_event(self, event):
393
465
  if self.empty():
394
466
  return
@@ -424,12 +496,6 @@ class ViewStrategy(LayerCollectionHandler):
424
496
  self.last_mouse_pos = position
425
497
  self.scroll_view(master_view, delta.x(), delta.y())
426
498
 
427
- def scroll_view(self, view, delta_x, delta_y):
428
- view.horizontalScrollBar().setValue(
429
- view.horizontalScrollBar().value() - delta_x)
430
- view.verticalScrollBar().setValue(
431
- view.verticalScrollBar().value() - delta_y)
432
-
433
499
  def mouse_press_event(self, event):
434
500
  if self.empty():
435
501
  return
@@ -464,3 +530,28 @@ class ViewStrategy(LayerCollectionHandler):
464
530
  elif self.dragging:
465
531
  self.dragging = False
466
532
  self.brush_operation_ended.emit()
533
+
534
+ def handle_pinch_gesture(self, pinch):
535
+ master_view = self.get_master_view()
536
+ if pinch.state() == Qt.GestureStarted:
537
+ self.pinch_start_scale = self.zoom_factor()
538
+ self.pinch_center_view = pinch.centerPoint()
539
+ self.pinch_center_scene = master_view.mapToScene(self.pinch_center_view.toPoint())
540
+ self.gesture_active = True
541
+ elif pinch.state() == Qt.GestureUpdated:
542
+ new_scale = self.pinch_start_scale * pinch.totalScaleFactor()
543
+ new_scale = max(self.min_scale(), min(new_scale, self.max_scale()))
544
+ if abs(new_scale - self.zoom_factor()) > 0.01:
545
+ self.set_zoom_factor(new_scale)
546
+ self.apply_zoom()
547
+ new_center = master_view.mapToScene(self.pinch_center_view.toPoint())
548
+ delta = self.pinch_center_scene - new_center
549
+ h_scroll = master_view.horizontalScrollBar().value() + \
550
+ int(delta.x() * self.zoom_factor())
551
+ v_scroll = master_view.verticalScrollBar().value() + \
552
+ int(delta.y() * self.zoom_factor())
553
+ self.status.set_scroll(h_scroll, v_scroll)
554
+ self.center_image(master_view)
555
+ elif pinch.state() in (Qt.GestureFinished, Qt.GestureCanceled):
556
+ self.gesture_active = False
557
+ self.update_cursor_pen_width()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shinestacker
3
- Version: 1.4.0
3
+ Version: 1.5.0
4
4
  Summary: ShineStacker
5
5
  Author-email: Luca Lista <luka.lista@gmail.com>
6
6
  License-Expression: LGPL-3.0
@@ -70,11 +70,11 @@ The GUI has two main working areas:
70
70
 
71
71
  <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/gui-retouch.png' width="600" referrerpolicy="no-referrer">
72
72
 
73
- # Resources
73
+ ## Resources
74
74
 
75
75
  🌍 [Website on WordPress](https://shinestacker.wordpress.com) • 📖 [Main documentation](https://shinestacker.readthedocs.io) • 📝 [Changelog](https://github.com/lucalista/shinestacker/blob/main/CHANGELOG.md)
76
76
 
77
- # Note for macOS users
77
+ ## Note for macOS users
78
78
 
79
79
  **The following note is only relevant if you download the application as compressed archive from the [release page](https://github.com/lucalista/shinestacker/releases).**
80
80
 
@@ -93,17 +93,17 @@ xattr -cr ~/Downloads/shinestacker/shinestacker.app
93
93
 
94
94
  macOS adds a quarantine flag to all files downloaded from the internet. The above command removes that flag while preserving all other application functionality.
95
95
 
96
- # Credits
96
+ ## Credits
97
97
 
98
98
  The first version of the core focus stack algorithm was initially inspired by the [Laplacian pyramids method](https://github.com/sjawhar/focus-stacking) implementation by Sami Jawhar that was used under permission of the author. The implementation in the latest releases was rewritten from the original code.
99
99
 
100
- # Resources
100
+ ## Resources
101
101
 
102
102
  * [Pyramid Methods in Image Processing](https://www.researchgate.net/publication/246727904_Pyramid_Methods_in_Image_Processing), E. H. Adelson, C. H. Anderson, J. R. Bergen, P. J. Burt, J. M. Ogden, RCA Engineer, 29-6, Nov/Dec 1984
103
103
  Pyramid methods in image processing
104
104
  * [A Multi-focus Image Fusion Method Based on Laplacian Pyramid](http://www.jcomputers.us/vol6/jcp0612-07.pdf), Wencheng Wang, Faliang Chang, Journal of Computers 6 (12), 2559, December 2011
105
105
 
106
- # License
106
+ ## License
107
107
 
108
108
  <img src="https://www.gnu.org/graphics/lgplv3-147x51.png" alt="LGPL 3 logo">
109
109
 
@@ -112,7 +112,7 @@ Pyramid methods in image processing
112
112
 
113
113
  - **Logo**: The Shine Stacker logo was designed by [Alessandro Lista](https://linktr.ee/alelista). Copyright © Alessandro Lista. All rights reserved. The logo is not covered by the LGPL-3.0 license of this project.
114
114
 
115
- # Attribution request
115
+ ## Attribution request
116
116
  📸 If you publish images created with Shine Stacker, please consider adding a note such as:
117
117
 
118
118
  *Created with Shine Stacker – https://github.com/lucalista/shinestacker*
@@ -1,5 +1,5 @@
1
1
  shinestacker/__init__.py,sha256=uq2fjAw2z_6TpH3mOcWFZ98GoEPRsNhTAK8N0MMm_e8,448
2
- shinestacker/_version.py,sha256=R4yO1-T_1mGmXG30xDxIA44z6cxCh-PK6l33V9MTqxk,21
2
+ shinestacker/_version.py,sha256=XyInpe-Rlf1hgwkiRXtR0uPYm4ZwRFpgchjcpZZ9Pms,21
3
3
  shinestacker/algorithms/__init__.py,sha256=1FwVJ3w9GGbFFkjYJRUedTvcdE4j0ieSgaH9RC9iCY4,877
4
4
  shinestacker/algorithms/align.py,sha256=mb44u-YxZI1TTSHz81nRpX_2c8awlOhnGrK0LyfTQeQ,33543
5
5
  shinestacker/algorithms/align_auto.py,sha256=pJetw6zZEWQLouzcelkI8gD4cPiOp887ePXzVbm0E6Q,3800
@@ -24,14 +24,14 @@ shinestacker/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
24
24
  shinestacker/app/about_dialog.py,sha256=pkH7nnxUP8yc0D3vRGd1jRb5cwi1nDVbQRk_OC9yLk8,4144
25
25
  shinestacker/app/gui_utils.py,sha256=fSpkwPXTON_l676UHdAnJNrGq7BPbSlPOiHpOF_LZaI,2519
26
26
  shinestacker/app/help_menu.py,sha256=g8lKG_xZmXtNQaC3SIRzyROKVWva_PLEgZsQWh6zUcQ,499
27
- shinestacker/app/main.py,sha256=XdWYUm1ed1q7aPghxgaFwWJVNijCvZZ_WG0fux8Nisc,10459
27
+ shinestacker/app/main.py,sha256=JRfobAg_stqk7FZbGWNQChfdQHRzMXqFzVXe1gOci_I,10459
28
28
  shinestacker/app/open_frames.py,sha256=bsu32iJSYJQLe_tQQbvAU5DuMDVX6MRuNdE7B5lojZc,1488
29
29
  shinestacker/app/project.py,sha256=oopOiqU6bOK1cQdpot88z49KbKrlB-LAz_q4-8Iui0U,2819
30
30
  shinestacker/app/retouch.py,sha256=dpSozNWSxL6wIO0SMjoviDbXZbbfRN_rVLjeL324c54,2527
31
31
  shinestacker/config/__init__.py,sha256=aXxi-LmAvXd0daIFrVnTHE5OCaYeK1uf1BKMr7oaXQs,197
32
32
  shinestacker/config/config.py,sha256=eBko2D3ADhLTIm9X6hB_a_WsIjwgfE-qmBVkhP1XSvc,1636
33
33
  shinestacker/config/constants.py,sha256=EEdr7pZg4JpbIjUWaP7kJQfTuBB85FN739myDNAfn8A,8301
34
- shinestacker/config/gui_constants.py,sha256=7oZtBaeUxzU7WmbcR7yvQVlzQyRUaIMRcxY3SrKRGOk,2589
34
+ shinestacker/config/gui_constants.py,sha256=YigJ5pRKjzjQKAN-ulosS6zLfnTj2BQESvVIvqXNzjA,2786
35
35
  shinestacker/core/__init__.py,sha256=IUEIx6SQ3DygDEHN3_E6uKpHjHtUa4a_U_1dLd_8yEU,484
36
36
  shinestacker/core/colors.py,sha256=kr_tJA1iRsdck2JaYDb2lS-codZ4Ty9gdu3kHfiWvuM,1340
37
37
  shinestacker/core/core_utils.py,sha256=1LYj19Dfc9jZN9-4dlf1paximDH5WZYa7DXvKr7R7QY,1719
@@ -70,34 +70,35 @@ shinestacker/gui/img/forward-button-icon.png,sha256=lNw86T4TOEd_uokHYF8myGSGUXzd
70
70
  shinestacker/gui/img/play-button-round-icon.png,sha256=9j6Ks9mOGa-2cXyRFpimepAAvSaHzqJKBfxShRb4_dE,4595
71
71
  shinestacker/gui/img/plus-round-line-icon.png,sha256=LS068Hlu-CeBvJuB3dwwdJg1lZq6D5MUIv53lu1yKJA,7534
72
72
  shinestacker/retouch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
- shinestacker/retouch/base_filter.py,sha256=l8sdqKJ8OS2EEwMVVF8DLLLqE_kvYudQ_nUBo_GnC-0,10346
73
+ shinestacker/retouch/base_filter.py,sha256=gvRGvhOhhWS05jKOXyNdMnia3b7rscQqR8-xnySIWFc,10260
74
74
  shinestacker/retouch/brush.py,sha256=dzD2FzSpBIPdJRmTZobcrQ1FrVd3tF__ZPnUplNE72s,357
75
75
  shinestacker/retouch/brush_gradient.py,sha256=F5SFhyzl8YTMqjJU3jK8BrIlLCYLUvITd5wz3cQE4xk,1453
76
- shinestacker/retouch/brush_preview.py,sha256=V-6yRH-paXOEC9bTCJ1NiE6xkTPUiJQGo1N61MMG1AI,4969
76
+ shinestacker/retouch/brush_preview.py,sha256=03x7Hh-5g4JEQgBCK5mGUtVDtiOnJPOdU1JgeUJhGaA,4945
77
77
  shinestacker/retouch/brush_tool.py,sha256=8uVncTA375uC3Nhp2YM0eZjpOR-nN47i2eGjN8tJzOU,8714
78
78
  shinestacker/retouch/denoise_filter.py,sha256=TDUHzhRKlKvCa3D5SCYCZKTpjcl81kGwmONsgSDtO1k,440
79
- shinestacker/retouch/display_manager.py,sha256=9HKCU8HFs3OyenEa2sk1FanaRCWpmPt77x6G4JfhJ-c,8888
79
+ shinestacker/retouch/display_manager.py,sha256=wwbX4n7ulg53fM3E5QL5YEb5IFV0jN8za6yfYc74anA,8624
80
80
  shinestacker/retouch/exif_data.py,sha256=LF-fRXW-reMq-xJ_QRE5j8DC2LVGKIlC6MR3QbC1cdg,1896
81
81
  shinestacker/retouch/file_loader.py,sha256=z02-A8_uDZxayI1NFTxT2GVUvEBWStchX9hlN1o5-0U,4784
82
82
  shinestacker/retouch/filter_manager.py,sha256=SdYIZkZBUvuB6wDG0moGWav5sfEvIcB9ioUJR5wJFts,388
83
83
  shinestacker/retouch/icon_container.py,sha256=6gw1HO1bC2FrdB4dc_iH81DQuLjzuvRGksZ2hKLT9yA,585
84
- shinestacker/retouch/image_editor_ui.py,sha256=Y7gzbgkWa3ehQ9dUahiY4TGoQPkwI00BHTGwobdm8L4,32442
85
- shinestacker/retouch/image_view_status.py,sha256=8M1IA0T2cATWhOx1Zv0K9u8yMkujSnWLqy5zlEEy5c4,1745
86
- shinestacker/retouch/image_viewer.py,sha256=TV4RsEGQC4nhpfS7MCjQDd-ASojcVZpbcFKbi-TuDhQ,4187
84
+ shinestacker/retouch/image_editor_ui.py,sha256=0EW-jnKrQz9Z_xLS51AltWul7lHst4fAvubiWNH-g2o,33456
85
+ shinestacker/retouch/image_view_status.py,sha256=bdIhsXiYXm7eyjkTGWkw5PRShzaF_by-g7daqgmhwjM,1858
86
+ shinestacker/retouch/image_viewer.py,sha256=jkFVuBxWxoZqtaOS8N1R8iZ9WnyGfKGdczEdET2KTWU,4452
87
87
  shinestacker/retouch/io_gui_handler.py,sha256=Upt8VWwDUrB-UnqCI54SQQwfR4w9kfznCdRL2UwupWQ,12010
88
88
  shinestacker/retouch/io_manager.py,sha256=JUAA--AK0mVa1PTErJTnBFjaXIle5Qs7Ow0Wkd8at0o,2437
89
- shinestacker/retouch/layer_collection.py,sha256=Q7zoCYRn__jYkfrEC2lY1uKHWfOUbsJ27xaYHIoKVxo,5730
90
- shinestacker/retouch/overlaid_view.py,sha256=J4r9DqHzhPrPgJ2IUGuAB26UGxkr2Kf50NUo_NM6w98,8468
89
+ shinestacker/retouch/layer_collection.py,sha256=fZlGrkm9-Ycc7AOzFSpImhafiTieBeCZRk-UlvlFHbo,5819
90
+ shinestacker/retouch/overlaid_view.py,sha256=NoFEwokTqbx41xnzYEHS0xhprHEAd2pRlH5NRAHxc2Y,7960
91
91
  shinestacker/retouch/shortcuts_help.py,sha256=EDxwR7MZwUC9NHLjvqAlh5iEHT9g3g8Tzl18VUGErI4,4130
92
- shinestacker/retouch/sidebyside_view.py,sha256=tS50VzmTc0Iqf9k3fIbQ3jeIIkDyOO_6TJoNiGg7pLI,19423
93
- shinestacker/retouch/undo_manager.py,sha256=_ekbcOLcPbQLY7t-o8wf-b1uA6OPY9rRyLM-KqMlQRo,3257
92
+ shinestacker/retouch/sidebyside_view.py,sha256=d9Pc2P_apTd0krsERIuEVc8RYBxiXs5tC7X9__t8TBc,18883
93
+ shinestacker/retouch/transformation_manager.py,sha256=NSHGUF-JFv4Y81gSvizjQCTp49TLo1so7c0WoUElO08,1812
94
+ shinestacker/retouch/undo_manager.py,sha256=cKUkqnJtnJ-Hq-LQs5Bv49FC6qkG6XSw9oCVySJ8jS0,4312
94
95
  shinestacker/retouch/unsharp_mask_filter.py,sha256=uFnth8fpZFGhdIgJCnS8x5v6lBQgJ3hX0CBke9pFXeM,3510
95
- shinestacker/retouch/view_strategy.py,sha256=DjBXWsrJJPU4UmdHIeqy_AI6ltDWHBr-RRaFwwYwc04,17061
96
+ shinestacker/retouch/view_strategy.py,sha256=ex_bNym9pBXk9GDcpZr1vh4sJXx4ytrzavLRkHzeEXc,21234
96
97
  shinestacker/retouch/vignetting_filter.py,sha256=MA97rQkSL0D-Nh-n2L4AiPR064RoTROkvza4tw84g9U,3658
97
98
  shinestacker/retouch/white_balance_filter.py,sha256=glMBYlmrF-i_OrB3sGUpjZE6X4FQdyLC4GBy2bWtaFc,6056
98
- shinestacker-1.4.0.dist-info/licenses/LICENSE,sha256=pWgb-bBdsU2Gd2kwAXxketnm5W_2u8_fIeWEgojfrxs,7651
99
- shinestacker-1.4.0.dist-info/METADATA,sha256=gqcYTHpTNsHmYEUz76mZzWXREe3d0D_iVmfesRQsyM0,6972
100
- shinestacker-1.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
101
- shinestacker-1.4.0.dist-info/entry_points.txt,sha256=SY6g1LqtMmp23q1DGwLUDT_dhLX9iss8DvWkiWLyo_4,166
102
- shinestacker-1.4.0.dist-info/top_level.txt,sha256=MhijwnBVX5psfsyX8JZjqp3SYiWPsKe69f3Gnyze4Fw,13
103
- shinestacker-1.4.0.dist-info/RECORD,,
99
+ shinestacker-1.5.0.dist-info/licenses/LICENSE,sha256=pWgb-bBdsU2Gd2kwAXxketnm5W_2u8_fIeWEgojfrxs,7651
100
+ shinestacker-1.5.0.dist-info/METADATA,sha256=FXzUo0Sa94vwqOVxvbUHFIeRrjRvGgNMqnmUgooYcIY,6978
101
+ shinestacker-1.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
102
+ shinestacker-1.5.0.dist-info/entry_points.txt,sha256=SY6g1LqtMmp23q1DGwLUDT_dhLX9iss8DvWkiWLyo_4,166
103
+ shinestacker-1.5.0.dist-info/top_level.txt,sha256=MhijwnBVX5psfsyX8JZjqp3SYiWPsKe69f3Gnyze4Fw,13
104
+ shinestacker-1.5.0.dist-info/RECORD,,