1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-02-07 10:59:49 +00:00

Compare commits

..

No commits in common. "ac950dafae07e3e021a018116a0a599a2234c01f" and "63691cacaf9e05bc0140e38c1102dcbf119d2a3b" have entirely different histories.

2 changed files with 67 additions and 39 deletions

View file

@ -11,13 +11,9 @@ Fayez Akhtar ([@Variable-ind](https://github.com/Variable-ind)), Clara Hobbs ([R
Built using Godot 4.2.1 Built using Godot 4.2.1
### Added ### Added
- Multiple layer blend modes are finally here! [#911](https://github.com/Orama-Interactive/Pixelorama/pull/911) - Support for multiple layer blend modes are finally here! [#911](https://github.com/Orama-Interactive/Pixelorama/pull/911)
- Non-destructive layer effects have been implemented. [#940](https://github.com/Orama-Interactive/Pixelorama/pull/940) - Non-destructive layer effects have been implemented. [#940](https://github.com/Orama-Interactive/Pixelorama/pull/940)
- An extension explorer has been integrated into Pixelorama, allowing for easy extension downloading from the internet. [#910](https://github.com/Orama-Interactive/Pixelorama/pull/910)
- Export to video formats. FFMPEG is required to be installed in the device in order for video exporting to work. [#980](https://github.com/Orama-Interactive/Pixelorama/pull/980)
- Export to webp and jpeg file formats. Webp is currently only for static images and does not support animations. - Export to webp and jpeg file formats. Webp is currently only for static images and does not support animations.
- Native file dialogs are now supported and can be enabled from the Preferences!
- Dialog popups can now be native OS windows instead of embedded within Pixelorama's main window. This can be changed from the Preferences.
- Added some missing shortcuts for buttons. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900) - Added some missing shortcuts for buttons. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900)
- Palette colors can now be sorted. - Palette colors can now be sorted.
- The brush increment/decrement shortcuts can now be changed. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900) - The brush increment/decrement shortcuts can now be changed. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900)
@ -48,7 +44,6 @@ Built using Godot 4.2.1
### Fixed ### Fixed
- Performance when drawing and doing operations such as bucket area fill should be better now. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900) - Performance when drawing and doing operations such as bucket area fill should be better now. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900)
- Selections now scale properly when they are not transforming any image content. [#774](https://github.com/Orama-Interactive/Pixelorama/issues/774)
- Dividing by zero in value sliders and spinboxes no longer crashes the program. - Dividing by zero in value sliders and spinboxes no longer crashes the program.
## [v0.11.4] - Unreleased ## [v0.11.4] - Unreleased
@ -74,11 +69,9 @@ Built using Godot 3.5.2
- Tool shortcuts can now work with <kbd>Control</kbd>. [#935](https://github.com/Orama-Interactive/Pixelorama/issues/935) - Tool shortcuts can now work with <kbd>Control</kbd>. [#935](https://github.com/Orama-Interactive/Pixelorama/issues/935)
- Optimize canvas drawing by only updating it when the image(s) have changed. [ac6a4db43d9296ebc03e639d8199dd3878a25d86](https://github.com/Orama-Interactive/Pixelorama/commit/ac6a4db43d9296ebc03e639d8199dd3878a25d86) - Optimize canvas drawing by only updating it when the image(s) have changed. [ac6a4db43d9296ebc03e639d8199dd3878a25d86](https://github.com/Orama-Interactive/Pixelorama/commit/ac6a4db43d9296ebc03e639d8199dd3878a25d86)
- Fix bug where using shortcuts to switch between frames also moved the selection, causing deletions. - Fix bug where using shortcuts to switch between frames also moved the selection, causing deletions.
- Pxo files can now be loaded from the Open menu option in the Web version. [3dcc51705a999145e53a8e6d4de217dc03b0f147](https://github.com/Orama-Interactive/Pixelorama/commit/3dcc51705a999145e53a8e6d4de217dc03b0f147)
- The ellipse tool no longer produces gaps with large sizes. [4f3a7a305a264e0d2fe86c201af76eca4b2fea0a](https://github.com/Orama-Interactive/Pixelorama/commit/4f3a7a305a264e0d2fe86c201af76eca4b2fea0a) - The ellipse tool no longer produces gaps with large sizes. [4f3a7a305a264e0d2fe86c201af76eca4b2fea0a](https://github.com/Orama-Interactive/Pixelorama/commit/4f3a7a305a264e0d2fe86c201af76eca4b2fea0a)
- Fix "visible layers" option on the export dialog producing wrong results. [346d1f071a8c6b1defb1072d39aea9c642f1ef59](https://github.com/Orama-Interactive/Pixelorama/commit/346d1f071a8c6b1defb1072d39aea9c642f1ef59) - Fix "visible layers" option on the export dialog producing wrong results. [346d1f071a8c6b1defb1072d39aea9c642f1ef59](https://github.com/Orama-Interactive/Pixelorama/commit/346d1f071a8c6b1defb1072d39aea9c642f1ef59)
- Random brushes now work again. [1317e40ffa5e9f01a9d214221bb5133db20a1de9](https://github.com/Orama-Interactive/Pixelorama/commit/1317e40ffa5e9f01a9d214221bb5133db20a1de9) - Random brushes now work again. [1317e40ffa5e9f01a9d214221bb5133db20a1de9](https://github.com/Orama-Interactive/Pixelorama/commit/1317e40ffa5e9f01a9d214221bb5133db20a1de9)
- The gizmo in the rotation image effect dialog is now accurately following the mouse.
## [v0.11.3] - 2023-10-30 ## [v0.11.3] - 2023-10-30
This update has been brought to you by the contributions of: This update has been brought to you by the contributions of:
@ -92,6 +85,7 @@ Built using Godot 3.5.2
### Fixed ### Fixed
- Fixed undo/redo history not working when the tool changes. [#916](https://github.com/Orama-Interactive/Pixelorama/pull/916) - Fixed undo/redo history not working when the tool changes. [#916](https://github.com/Orama-Interactive/Pixelorama/pull/916)
- Pixelorama no longer closes when the project fails to be saved if "Save & Exit" is selected. [#920](https://github.com/Orama-Interactive/Pixelorama/pull/920) - Pixelorama no longer closes when the project fails to be saved if "Save & Exit" is selected. [#920](https://github.com/Orama-Interactive/Pixelorama/pull/920)
- Projects with 3D cels saved in 1.x can now be opened in 0.11.3. [#928](https://github.com/Orama-Interactive/Pixelorama/pull/928)
## [v0.11.2] - 2023-08-31 ## [v0.11.2] - 2023-08-31
This update has been brought to you by the contributions of: This update has been brought to you by the contributions of:

View file

@ -156,22 +156,36 @@ func scale_3x(sprite: Image, tol := 50.0) -> Image:
var scaled := Image.create( var scaled := Image.create(
sprite.get_width() * 3, sprite.get_height() * 3, false, Image.FORMAT_RGBA8 sprite.get_width() * 3, sprite.get_height() * 3, false, Image.FORMAT_RGBA8
) )
var width_minus_one := sprite.get_width() - 1 var a: Color
var height_minus_one := sprite.get_height() - 1 var b: Color
var c: Color
var d: Color
var e: Color
var f: Color
var g: Color
var h: Color
var i: Color
for x in range(0, sprite.get_width()): for x in range(0, sprite.get_width()):
for y in range(0, sprite.get_height()): for y in range(0, sprite.get_height()):
var xs := 3 * x var xs := 3 * x
var ys := 3 * y var ys := 3 * y
var a := sprite.get_pixel(maxi(x - 1, 0), maxi(y - 1, 0)) a = sprite.get_pixel(maxi(x - 1, 0), maxi(y - 1, 0))
var b := sprite.get_pixel(mini(x, width_minus_one), maxi(y - 1, 0)) b = sprite.get_pixel(mini(x, sprite.get_width() - 1), maxi(y - 1, 0))
var c := sprite.get_pixel(mini(x + 1, width_minus_one), maxi(y - 1, 0)) c = sprite.get_pixel(mini(x + 1, sprite.get_width() - 1), maxi(y - 1, 0))
var d := sprite.get_pixel(maxi(x - 1, 0), mini(y, height_minus_one)) d = sprite.get_pixel(maxi(x - 1, 0), mini(y, sprite.get_height() - 1))
var e := sprite.get_pixel(mini(x, width_minus_one), mini(y, height_minus_one)) e = sprite.get_pixel(mini(x, sprite.get_width() - 1), mini(y, sprite.get_height() - 1))
var f := sprite.get_pixel(mini(x + 1, width_minus_one), mini(y, height_minus_one)) f = sprite.get_pixel(
var g := sprite.get_pixel(maxi(x - 1, 0), mini(y + 1, height_minus_one)) mini(x + 1, sprite.get_width() - 1), mini(y, sprite.get_height() - 1)
var h := sprite.get_pixel(mini(x, width_minus_one), mini(y + 1, height_minus_one)) )
var i := sprite.get_pixel(mini(x + 1, width_minus_one), mini(y + 1, height_minus_one)) g = sprite.get_pixel(maxi(x - 1, 0), mini(y + 1, sprite.get_height() - 1))
h = sprite.get_pixel(
mini(x, sprite.get_width() - 1), mini(y + 1, sprite.get_height() - 1)
)
i = sprite.get_pixel(
mini(x + 1, sprite.get_width() - 1), mini(y + 1, sprite.get_height() - 1)
)
var db: bool = similar_colors(d, b, tol) var db: bool = similar_colors(d, b, tol)
var dh: bool = similar_colors(d, h, tol) var dh: bool = similar_colors(d, h, tol)
@ -209,7 +223,7 @@ func scale_3x(sprite: Image, tol := 50.0) -> Image:
func rotxel(sprite: Image, angle: float, pivot: Vector2) -> void: func rotxel(sprite: Image, angle: float, pivot: Vector2) -> void:
# If angle is simple, then nn rotation is the best # If angle is simple, then nn rotation is the best
if angle == 0 || angle == PI / 2 || angle == PI || angle == 3.0 * PI / 2.0 || angle == TAU: if angle == 0 || angle == PI / 2 || angle == PI || angle == 2 * PI:
nn_rotate(sprite, angle, pivot) nn_rotate(sprite, angle, pivot)
return return
@ -217,6 +231,7 @@ func rotxel(sprite: Image, angle: float, pivot: Vector2) -> void:
aux.copy_from(sprite) aux.copy_from(sprite)
var ox: int var ox: int
var oy: int var oy: int
var p: Color
for x in sprite.get_size().x: for x in sprite.get_size().x:
for y in sprite.get_size().y: for y in sprite.get_size().y:
var dx := 3 * (x - pivot.x) var dx := 3 * (x - pivot.x)
@ -254,19 +269,27 @@ func rotxel(sprite: Image, angle: float, pivot: Vector2) -> void:
ox = roundi((ox - 1) / 3.0) ox = roundi((ox - 1) / 3.0)
oy = roundi((oy - 1) / 3.0) oy = roundi((oy - 1) / 3.0)
var p: Color var a: Color
var b: Color
var c: Color
var d: Color
var e: Color
var f: Color
var g: Color
var h: Color
var i: Color
if ox == 0 || ox == sprite.get_width() - 1 || oy == 0 || oy == sprite.get_height() - 1: if ox == 0 || ox == sprite.get_width() - 1 || oy == 0 || oy == sprite.get_height() - 1:
p = aux.get_pixel(ox, oy) p = aux.get_pixel(ox, oy)
else: else:
var a := aux.get_pixel(ox - 1, oy - 1) a = aux.get_pixel(ox - 1, oy - 1)
var b := aux.get_pixel(ox, oy - 1) b = aux.get_pixel(ox, oy - 1)
var c := aux.get_pixel(ox + 1, oy - 1) c = aux.get_pixel(ox + 1, oy - 1)
var d := aux.get_pixel(ox - 1, oy) d = aux.get_pixel(ox - 1, oy)
var e := aux.get_pixel(ox, oy) e = aux.get_pixel(ox, oy)
var f := aux.get_pixel(ox + 1, oy) f = aux.get_pixel(ox + 1, oy)
var g := aux.get_pixel(ox - 1, oy + 1) g = aux.get_pixel(ox - 1, oy + 1)
var h := aux.get_pixel(ox, oy + 1) h = aux.get_pixel(ox, oy + 1)
var i := aux.get_pixel(ox + 1, oy + 1) i = aux.get_pixel(ox + 1, oy + 1)
match index: match index:
0: 0:
@ -391,7 +414,9 @@ func rotxel(sprite: Image, angle: float, pivot: Vector2) -> void:
func fake_rotsprite(sprite: Image, angle: float, pivot: Vector2) -> void: func fake_rotsprite(sprite: Image, angle: float, pivot: Vector2) -> void:
var selected_sprite := scale_3x(sprite) var selected_sprite := Image.new()
selected_sprite.copy_from(sprite)
selected_sprite.copy_from(scale_3x(selected_sprite))
nn_rotate(selected_sprite, angle, pivot * 3) nn_rotate(selected_sprite, angle, pivot * 3)
selected_sprite.resize( selected_sprite.resize(
selected_sprite.get_width() / 3, selected_sprite.get_height() / 3, Image.INTERPOLATE_NEAREST selected_sprite.get_width() / 3, selected_sprite.get_height() / 3, Image.INTERPOLATE_NEAREST
@ -404,12 +429,12 @@ func nn_rotate(sprite: Image, angle: float, pivot: Vector2) -> void:
return return
var aux := Image.new() var aux := Image.new()
aux.copy_from(sprite) aux.copy_from(sprite)
var angle_sin := sin(angle) var ox: int
var angle_cos := cos(angle) var oy: int
for x in range(sprite.get_width()): for x in range(sprite.get_width()):
for y in range(sprite.get_height()): for y in range(sprite.get_height()):
var ox := (x - pivot.x) * angle_cos + (y - pivot.y) * angle_sin + pivot.x ox = (x - pivot.x) * cos(angle) + (y - pivot.y) * sin(angle) + pivot.x
var oy := -(x - pivot.x) * angle_sin + (y - pivot.y) * angle_cos + pivot.y oy = -(x - pivot.x) * sin(angle) + (y - pivot.y) * cos(angle) + pivot.y
if ox >= 0 && ox < sprite.get_width() && oy >= 0 && oy < sprite.get_height(): if ox >= 0 && ox < sprite.get_width() && oy >= 0 && oy < sprite.get_height():
sprite.set_pixel(x, y, aux.get_pixel(ox, oy)) sprite.set_pixel(x, y, aux.get_pixel(ox, oy))
else: else:
@ -417,10 +442,19 @@ func nn_rotate(sprite: Image, angle: float, pivot: Vector2) -> void:
func similar_colors(c1: Color, c2: Color, tol := 100.0) -> bool: func similar_colors(c1: Color, c2: Color, tol := 100.0) -> bool:
var v1 := Vector4(c1.r, c1.g, c1.b, c1.a) var dist := color_distance(c1, c2)
var v2 := Vector4(c2.r, c2.g, c2.b, c2.a) return dist <= tol
var dist := v2.distance_to(v1)
return dist <= (tol / 255.0)
func color_distance(c1: Color, c2: Color) -> float:
return sqrt(
(
pow((c1.r - c2.r) * 255, 2)
+ pow((c1.g - c2.g) * 255, 2)
+ pow((c1.b - c2.b) * 255, 2)
+ pow((c1.a - c2.a) * 255, 2)
)
)
# Image effects # Image effects