diff --git a/src/Autoload/DrawingAlgos.gd b/src/Autoload/DrawingAlgos.gd
index 64710ae2c..b8740bcd5 100644
--- a/src/Autoload/DrawingAlgos.gd
+++ b/src/Autoload/DrawingAlgos.gd
@@ -62,146 +62,163 @@ func scale3X(sprite : Image, tol : float = 50) -> Image:
 	return scaled
 
 
-func rotxel(sprite : Image, angle : float) -> void:
+func rotxel(sprite : Image, angle : float, pixels : Array) -> void:
 	# If angle is simple, then nn rotation is the best
-
 	if angle == 0 || angle == PI/2 || angle == PI || angle == 2*PI:
-		nn_rotate(sprite, angle)
+		nn_rotate(sprite, angle, pixels)
 		return
 
 	var aux : Image = Image.new()
 	aux.copy_from(sprite)
-# warning-ignore:integer_division
-# warning-ignore:integer_division
-	var center : Vector2 = Vector2(sprite.get_width() / 2, sprite.get_height() / 2)
+	var selection_rectangle := Rect2(pixels[0].x, pixels[0].y, pixels[-1].x - pixels[0].x + 1, pixels[-1].y - pixels[0].y + 1)
+	var center : Vector2 = selection_rectangle.position + ((selection_rectangle.end - selection_rectangle.position) / 2)
 	var ox : int
 	var oy : int
 	var p : Color
 	aux.lock()
 	sprite.lock()
-	for x in range(sprite.get_width()):
-		for y in range(sprite.get_height()):
-			var dx = 3*(x - center.x)
-			var dy = 3*(y - center.y)
-			var found_pixel : bool = false
-			for k in range(9):
-				var i = -1 + k % 3
+	for pix in pixels:
+		var x = pix.x
+		var y = pix.y
+		var dx = 3*(x - center.x)
+		var dy = 3*(y - center.y)
+		var found_pixel : bool = false
+		for k in range(9):
+			var i = -1 + k % 3
 # warning-ignore:integer_division
-				var j = -1 + int(k / 3)
-				var dir = atan2(dy + j, dx + i)
-				var mag = sqrt(pow(dx + i, 2) + pow(dy + j, 2))
-				dir -= angle
-				ox = round(center.x*3 + 1 + mag*cos(dir))
-				oy = round(center.y*3 + 1 + mag*sin(dir))
+			var j = -1 + int(k / 3)
+			var dir = atan2(dy + j, dx + i)
+			var mag = sqrt(pow(dx + i, 2) + pow(dy + j, 2))
+			dir -= angle
+			ox = round(center.x*3 + 1 + mag*cos(dir))
+			oy = round(center.y*3 + 1 + mag*sin(dir))
 
-				if (sprite.get_width() % 2 != 0):
-					ox += 1
-					oy += 1
+			if (sprite.get_width() % 2 != 0):
+				ox += 1
+				oy += 1
 
-				if (ox >= 0 && ox < sprite.get_width()*3
-					&& oy >= 0 && oy < sprite.get_height()*3):
-						found_pixel = true
-						break
+			if (ox >= 0 && ox < sprite.get_width()*3
+				&& oy >= 0 && oy < sprite.get_height()*3):
+					found_pixel = true
+					break
 
-			if !found_pixel:
-				sprite.set_pixel(x, y, Color(0,0,0,0))
-				continue
+		if !found_pixel:
+			sprite.set_pixel(x, y, Color(0,0,0,0))
+			continue
 
-			var fil : int = oy % 3
-			var col : int = ox % 3
-			var index : int = col + 3*fil
+		var fil : int = oy % 3
+		var col : int = ox % 3
+		var index : int = col + 3*fil
 
-			ox = round((ox - 1)/3.0);
-			oy = round((oy - 1)/3.0);
-			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):
-					p = aux.get_pixel(ox, oy)
-			else:
-				a = aux.get_pixel(ox-1,oy-1);
-				b = aux.get_pixel(ox,oy-1);
-				c = aux.get_pixel(ox+1,oy-1);
-				d = aux.get_pixel(ox-1,oy);
-				e = aux.get_pixel(ox,oy);
-				f = aux.get_pixel(ox+1,oy);
-				g = aux.get_pixel(ox-1,oy+1);
-				h = aux.get_pixel(ox,oy+1);
-				i = aux.get_pixel(ox+1,oy+1);
+		ox = round((ox - 1)/3.0);
+		oy = round((oy - 1)/3.0);
+		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):
+				p = aux.get_pixel(ox, oy)
+		else:
+			a = aux.get_pixel(ox-1,oy-1);
+			b = aux.get_pixel(ox,oy-1);
+			c = aux.get_pixel(ox+1,oy-1);
+			d = aux.get_pixel(ox-1,oy);
+			e = aux.get_pixel(ox,oy);
+			f = aux.get_pixel(ox+1,oy);
+			g = aux.get_pixel(ox-1,oy+1);
+			h = aux.get_pixel(ox,oy+1);
+			i = aux.get_pixel(ox+1,oy+1);
 
-				match(index):
-					0:
-						p = d if (similarColors(d,b) && !similarColors(d,h)
-						 && !similarColors(b,f)) else e;
-					1:
-						p = b if ((similarColors(d,b) && !similarColors(d,h) &&
-						 !similarColors(b,f) && !similarColors(e,c)) ||
-						 (similarColors(b,f) && !similarColors(d,b) &&
-						 !similarColors(f,h) && !similarColors(e,a))) else e;
-					2:
-						p = f if (similarColors(b,f) && !similarColors(d,b) &&
-						 !similarColors(f,h)) else e;
-					3:
-						p = d if ((similarColors(d,h) && !similarColors(f,h) &&
-						 !similarColors(d,b) && !similarColors(e,a)) ||
-						 (similarColors(d,b) && !similarColors(d,h) &&
-						!similarColors(b,f) && !similarColors(e,g))) else e;
-					4:
-						p = e
-					5:
-						p =  f if((similarColors(b,f) && !similarColors(d,b) &&
-						 !similarColors(f,h) && !similarColors(e,i))
-						 || (similarColors(f,h) && !similarColors(b,f) &&
-						 !similarColors(d,h) && !similarColors(e,c))) else e;
-					6:
-						p = d if (similarColors(d,h) && !similarColors(f,h) &&
-						 !similarColors(d,b)) else e;
-					7:
-						p = h if ((similarColors(f,h) && !similarColors(f,b) &&
-						 !similarColors(d,h) && !similarColors(e,g))
-						 || (similarColors(d,h) && !similarColors(f,h) &&
-						 !similarColors(d,b) && !similarColors(e,i))) else e;
-					8:
-						p = f if (similarColors(f,h) && !similarColors(f,b) &&
-						 !similarColors(d,h)) else e;
-			sprite.set_pixel(x, y, p)
+			match(index):
+				0:
+					p = d if (similarColors(d,b) && !similarColors(d,h)
+					 && !similarColors(b,f)) else e;
+				1:
+					p = b if ((similarColors(d,b) && !similarColors(d,h) &&
+					 !similarColors(b,f) && !similarColors(e,c)) ||
+					 (similarColors(b,f) && !similarColors(d,b) &&
+					 !similarColors(f,h) && !similarColors(e,a))) else e;
+				2:
+					p = f if (similarColors(b,f) && !similarColors(d,b) &&
+					 !similarColors(f,h)) else e;
+				3:
+					p = d if ((similarColors(d,h) && !similarColors(f,h) &&
+					 !similarColors(d,b) && !similarColors(e,a)) ||
+					 (similarColors(d,b) && !similarColors(d,h) &&
+					!similarColors(b,f) && !similarColors(e,g))) else e;
+				4:
+					p = e
+				5:
+					p =  f if((similarColors(b,f) && !similarColors(d,b) &&
+					 !similarColors(f,h) && !similarColors(e,i))
+					 || (similarColors(f,h) && !similarColors(b,f) &&
+					 !similarColors(d,h) && !similarColors(e,c))) else e;
+				6:
+					p = d if (similarColors(d,h) && !similarColors(f,h) &&
+					 !similarColors(d,b)) else e;
+				7:
+					p = h if ((similarColors(f,h) && !similarColors(f,b) &&
+					 !similarColors(d,h) && !similarColors(e,g))
+					 || (similarColors(d,h) && !similarColors(f,h) &&
+					 !similarColors(d,b) && !similarColors(e,i))) else e;
+				8:
+					p = f if (similarColors(f,h) && !similarColors(f,b) &&
+					 !similarColors(d,h)) else e;
+		sprite.set_pixel(x, y, p)
 	sprite.unlock()
 	aux.unlock()
 
 
-func fake_rotsprite(sprite : Image, angle : float) -> void:
-	sprite.copy_from(scale3X(sprite))
-	nn_rotate(sprite,angle)
+func fake_rotsprite(sprite : Image, angle : float, pixels : Array) -> void:
+	var selection_rectangle := Rect2(pixels[0].x, pixels[0].y, pixels[-1].x - pixels[0].x + 1, pixels[-1].y - pixels[0].y + 1)
+	var selected_sprite := Image.new()
+	selected_sprite = sprite.get_rect(selection_rectangle)
+	selected_sprite.copy_from(scale3X(selected_sprite))
+	nn_rotate(selected_sprite, angle, [])
 # warning-ignore:integer_division
 # warning-ignore:integer_division
-	sprite.resize(sprite.get_width() / 3, sprite.get_height() / 3, 0)
+	selected_sprite.resize(selected_sprite.get_width() / 3, selected_sprite.get_height() / 3, 0)
+	sprite.blit_rect(selected_sprite, Rect2(Vector2.ZERO, selected_sprite.get_size()), selection_rectangle.position)
 
 
-func nn_rotate(sprite : Image, angle : float) -> void:
+func nn_rotate(sprite : Image, angle : float, pixels : Array) -> void:
 	var aux : Image = Image.new()
 	aux.copy_from(sprite)
 	sprite.lock()
 	aux.lock()
 	var ox: int
 	var oy: int
-# warning-ignore:integer_division
-# warning-ignore:integer_division
-	var center : Vector2 = Vector2(sprite.get_width() / 2, sprite.get_height() / 2)
-	for x in range(sprite.get_width()):
-		for y in range(sprite.get_height()):
+	var center : Vector2
+	if pixels:
+		var selection_rectangle := Rect2(pixels[0].x, pixels[0].y, pixels[-1].x - pixels[0].x + 1, pixels[-1].y - pixels[0].y + 1)
+		center = selection_rectangle.position + ((selection_rectangle.end - selection_rectangle.position) / 2)
+		for pix in pixels:
+			var x = pix.x
+			var y = pix.y
 			ox = (x - center.x)*cos(angle) + (y - center.y)*sin(angle) + center.x
 			oy = -(x - center.x)*sin(angle) + (y - center.y)*cos(angle) + center.y
 			if ox >= 0 && ox < sprite.get_width() && oy >= 0 && oy < sprite.get_height():
 				sprite.set_pixel(x, y, aux.get_pixel(ox, oy))
 			else:
 				sprite.set_pixel(x, y, Color(0,0,0,0))
+	else:
+# warning-ignore:integer_division
+# warning-ignore:integer_division
+		center = Vector2(sprite.get_width() / 2, sprite.get_height() / 2)
+		for x in range(sprite.get_width()):
+			for y in range(sprite.get_height()):
+				ox = (x - center.x)*cos(angle) + (y - center.y)*sin(angle) + center.x
+				oy = -(x - center.x)*sin(angle) + (y - center.y)*cos(angle) + center.y
+				if ox >= 0 && ox < sprite.get_width() && oy >= 0 && oy < sprite.get_height():
+					sprite.set_pixel(x, y, aux.get_pixel(ox, oy))
+				else:
+					sprite.set_pixel(x, y, Color(0,0,0,0))
 	sprite.unlock()
 	aux.unlock()
 
diff --git a/src/UI/Dialogs/ImageEffects/RotateImage.gd b/src/UI/Dialogs/ImageEffects/RotateImage.gd
index 6a3cb733b..8aa5dcd95 100644
--- a/src/UI/Dialogs/ImageEffects/RotateImage.gd
+++ b/src/UI/Dialogs/ImageEffects/RotateImage.gd
@@ -14,6 +14,8 @@ func _ready() -> void:
 
 func set_nodes() -> void:
 	preview = $VBoxContainer/Preview
+	selection_checkbox = $VBoxContainer/OptionsContainer/SelectionCheckBox
+	affect_option_button = $VBoxContainer/OptionsContainer/AffectOptionButton
 
 
 func _about_to_show() -> void:
@@ -22,13 +24,14 @@ func _about_to_show() -> void:
 
 
 func commit_action(_cel : Image, _pixels : Array, _project : Project = Global.current_project) -> void:
+	var angle : float = deg2rad(angle_hslider.value)
 	match type_option_button.text:
 		"Rotxel":
-			DrawingAlgos.rotxel(_cel,angle_hslider.value*PI/180)
+			DrawingAlgos.rotxel(_cel, angle, _pixels)
 		"Nearest neighbour":
-			DrawingAlgos.nn_rotate(_cel,angle_hslider.value*PI/180)
+			DrawingAlgos.nn_rotate(_cel, angle, _pixels)
 		"Upscale, Rotate and Downscale":
-			DrawingAlgos.fake_rotsprite(_cel,angle_hslider.value*PI/180)
+			DrawingAlgos.fake_rotsprite(_cel, angle, _pixels)
 
 
 func _confirmed() -> void:
diff --git a/src/UI/Dialogs/ImageEffects/RotateImage.tscn b/src/UI/Dialogs/ImageEffects/RotateImage.tscn
index 029745f39..015751498 100644
--- a/src/UI/Dialogs/ImageEffects/RotateImage.tscn
+++ b/src/UI/Dialogs/ImageEffects/RotateImage.tscn
@@ -25,8 +25,8 @@ __meta__ = {
 }
 
 [node name="Preview" type="TextureRect" parent="VBoxContainer"]
-margin_left = 14.0
-margin_right = 214.0
+margin_left = 31.0
+margin_right = 231.0
 margin_bottom = 200.0
 rect_min_size = Vector2( 200, 200 )
 size_flags_horizontal = 4
@@ -39,7 +39,7 @@ show_behind_parent = true
 
 [node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer"]
 margin_top = 204.0
-margin_right = 229.0
+margin_right = 263.0
 margin_bottom = 224.0
 
 [node name="Label" type="Label" parent="VBoxContainer/HBoxContainer2"]
@@ -50,7 +50,7 @@ text = "Type:"
 
 [node name="TypeOptionButton" type="OptionButton" parent="VBoxContainer/HBoxContainer2"]
 margin_left = 38.0
-margin_right = 229.0
+margin_right = 263.0
 margin_bottom = 20.0
 mouse_default_cursor_shape = 2
 size_flags_horizontal = 3
@@ -58,7 +58,7 @@ size_flags_vertical = 3
 
 [node name="AngleOptions" type="HBoxContainer" parent="VBoxContainer"]
 margin_top = 228.0
-margin_right = 229.0
+margin_right = 263.0
 margin_bottom = 252.0
 
 [node name="Label" type="Label" parent="VBoxContainer/AngleOptions"]
@@ -69,7 +69,7 @@ text = "Angle:"
 
 [node name="AngleHSlider" type="HSlider" parent="VBoxContainer/AngleOptions"]
 margin_left = 44.0
-margin_right = 151.0
+margin_right = 185.0
 margin_bottom = 24.0
 mouse_default_cursor_shape = 2
 size_flags_horizontal = 3
@@ -80,12 +80,33 @@ __meta__ = {
 }
 
 [node name="AngleSpinBox" type="SpinBox" parent="VBoxContainer/AngleOptions"]
-margin_left = 155.0
-margin_right = 229.0
+margin_left = 189.0
+margin_right = 263.0
 margin_bottom = 24.0
 mouse_default_cursor_shape = 2
 max_value = 359.0
 suffix = "°"
+
+[node name="OptionsContainer" type="HBoxContainer" parent="VBoxContainer"]
+margin_top = 256.0
+margin_right = 263.0
+margin_bottom = 280.0
+
+[node name="SelectionCheckBox" type="CheckBox" parent="VBoxContainer/OptionsContainer"]
+margin_right = 160.0
+margin_bottom = 24.0
+mouse_default_cursor_shape = 2
+pressed = true
+text = "Only affect selection"
+
+[node name="AffectOptionButton" type="OptionButton" parent="VBoxContainer/OptionsContainer"]
+margin_left = 164.0
+margin_right = 263.0
+margin_bottom = 24.0
+mouse_default_cursor_shape = 2
+text = "Current cel"
+items = [ "Current cel", null, false, 0, null, "Current frame", null, false, 1, null, "All frames", null, false, 2, null, "All projects", null, false, 3, null ]
+selected = 0
 [connection signal="item_selected" from="VBoxContainer/HBoxContainer2/TypeOptionButton" to="." method="_on_TypeOptionButton_item_selected"]
 [connection signal="value_changed" from="VBoxContainer/AngleOptions/AngleHSlider" to="." method="_on_HSlider_value_changed"]
 [connection signal="value_changed" from="VBoxContainer/AngleOptions/AngleSpinBox" to="." method="_on_SpinBox_value_changed"]