Repository: python-pillow/Pillow

Issue:
Draw on a ico file without having to convert to png
### What did you do?
Load an ico image, draw lines and save it. 

### What did you expect to happen?
I expect to get lines on the `.ico` image
### What actually happened?
No lines

### The solution
I have to load the `.ico`  image, save it as a png , reload the png and finally draw the line on the png. 

### Feature request
That would be nice to be able to draw line on `.ico` files or if it's not possible to implement this workaround on the "back side"

### What are your OS, Python and Pillow versions?

* OS: Windows 10
* Python: 3.6
* Pillow: 5.1.0

```python

from PIL import Image, ImageDraw,ImageFont

#create an ico file: this step is just for debug, I already have a `ico` file
img = Image.new('RGB', (50, 50), (125, 167, 242)) 
img.save('a1.ico')  

#code start here
im = Image.open('a1.ico').save('a1.png')
im = Image.open('a1.png')
d = ImageDraw.Draw(im)
d.line((0, 0) + im.size, fill=128)
d.line((0, im.size[1], im.size[0], 0), fill=128)
im.save('pil_modif.ico')  

```



Discussion:
Thanks for reporting this problem. For your immediate use until this is resolved, I can suggest using `im.copy()` instead of needing to save it and then load it again -

```python
from PIL import Image, ImageDraw,ImageFont

#create an ico file: this step is just for debug, I already have a `ico` file
img = Image.new('RGB', (50, 50), (125, 167, 242)) 
img.save('a1.ico')  

#code start here
im = Image.open('a1.ico')
im = im.copy()
d = ImageDraw.Draw(im)
d.line((0, 0) + im.size, fill=128)
d.line((0, im.size[1], im.size[0], 0), fill=128)
im.save('pil_modif.ico')
```

Resolving patch:
diff --git a/src/PIL/IcnsImagePlugin.py b/src/PIL/IcnsImagePlugin.py
--- a/src/PIL/IcnsImagePlugin.py
+++ b/src/PIL/IcnsImagePlugin.py
@@ -251,8 +251,6 @@ def _open(self):
             self.best_size[0] * self.best_size[2],
             self.best_size[1] * self.best_size[2],
         )
-        # Just use this to see if it's loaded or not yet.
-        self.tile = ("",)
 
     @property
     def size(self):
@@ -286,7 +284,8 @@ def load(self):
             )
 
         Image.Image.load(self)
-        if not self.tile:
+        if self.im and self.im.size == self.size:
+            # Already loaded
             return
         self.load_prepare()
         # This is likely NOT the best way to do it, but whatever.
@@ -298,11 +297,6 @@ def load(self):
         self.im = im.im
         self.mode = im.mode
         self.size = im.size
-        if self._exclusive_fp:
-            self.fp.close()
-        self.fp = None
-        self.icns = None
-        self.tile = ()
         self.load_end()
 
 
diff --git a/src/PIL/IcoImagePlugin.py b/src/PIL/IcoImagePlugin.py
--- a/src/PIL/IcoImagePlugin.py
+++ b/src/PIL/IcoImagePlugin.py
@@ -288,6 +288,9 @@ def size(self, value):
         self._size = value
 
     def load(self):
+        if self.im and self.im.size == self.size:
+            # Already loaded
+            return
         im = self.ico.getimage(self.size)
         # if tile is PNG, it won't really be loaded yet
         im.load()


Test patch:
diff --git a/Tests/images/hopper_draw.ico b/Tests/images/hopper_draw.ico
new file mode 100644
Binary files /dev/null and b/Tests/images/hopper_draw.ico differ
diff --git a/Tests/test_file_icns.py b/Tests/test_file_icns.py
--- a/Tests/test_file_icns.py
+++ b/Tests/test_file_icns.py
@@ -61,11 +61,10 @@ def test_sizes(self):
         for w, h, r in im.info['sizes']:
             wr = w * r
             hr = h * r
-            im2 = Image.open(TEST_FILE)
-            im2.size = (w, h, r)
-            im2.load()
-            self.assertEqual(im2.mode, 'RGBA')
-            self.assertEqual(im2.size, (wr, hr))
+            im.size = (w, h, r)
+            im.load()
+            self.assertEqual(im.mode, 'RGBA')
+            self.assertEqual(im.size, (wr, hr))
 
         # Check that we cannot load an incorrect size
         with self.assertRaises(ValueError):
diff --git a/Tests/test_file_ico.py b/Tests/test_file_ico.py
--- a/Tests/test_file_ico.py
+++ b/Tests/test_file_ico.py
@@ -1,7 +1,7 @@
 from .helper import PillowTestCase, hopper
 
 import io
-from PIL import Image, IcoImagePlugin
+from PIL import Image, ImageDraw, IcoImagePlugin
 
 TEST_ICO_FILE = "Tests/images/hopper.ico"
 
@@ -90,3 +90,16 @@ def test_unexpected_size(self):
         im = self.assert_warning(UserWarning,
                                  Image.open, "Tests/images/hopper_unexpected.ico")
         self.assertEqual(im.size, (16, 16))
+
+    def test_draw_reloaded(self):
+        im = Image.open(TEST_ICO_FILE)
+        outfile = self.tempfile("temp_saved_hopper_draw.ico")
+
+        draw = ImageDraw.Draw(im)
+        draw.line((0, 0) + im.size, '#f00')
+        im.save(outfile)
+
+        im = Image.open(outfile)
+        im.save("Tests/images/hopper_draw.ico")
+        reloaded = Image.open("Tests/images/hopper_draw.ico")
+        self.assert_image_equal(im, reloaded)