It may also depend on which file format you save into. Due to the different compression algorithms used in various formats, bitwise identity might not be assured. I would recommend doing a test with an uncompressed format like TIFF (be aware that TIFF also has a compressed variant, but take the uncompressed), and verify that you’re getting the exact same number of bytes of file each time. You then MIGHT get the exact same file.
But I would be inclined to work differently. More on that later. For these examples, I took this 1x1 PNG (base64’d for the post):
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNgAAIAAAUAAen63NgAAAAASUVORK5CYII=
which has this SHA256: 2aa4fa20701cdd6d8d56046069001186b5267e3ee7d0ef618ad2f4a683723e11
Now, I could resize this up to 50x50, then re-encode it to PNG. and save it as a file. (I didn’t use PIL for this, used imagemagick instead, but the same effect happens.) These are the files:
b68999e40c9ef6a0f20884b5e21411a6016e6000c1ce89518e5ce756e942fa4c test50:1.png
f8b3d7f8d8ddbd4d78e155a1a59a3b571a7e5f6f5a1abb319fd3622c80ad3570 test50:2.png
5f9ef5eba314d44008ecbf48c6c2e66cd34a3dfb57160fb6c2debed177be6823 test50:3.png
f23609f2b5d6e1390fbc77808cc93a50a202b7be2cedaa7d1c475fe51dca454d test50:4.png
1870451f5d518eb5261edf634e953644d69e456f0a731c1452333b19e9957e0f test50:5.png
So, even with the exact same command, same library, etc, no you’re not guaranteed the same result. (These files all have the same file size, but they aren’t bit-for-bit identical.)
Using TIFF, I do achieve bitwise identical files:
96d82681cf9a24452d5a63ce2044f5184d9686e366676d92fb5e7ffbb7fdf493 test50:1.tiff
96d82681cf9a24452d5a63ce2044f5184d9686e366676d92fb5e7ffbb7fdf493 test50:2.tiff
96d82681cf9a24452d5a63ce2044f5184d9686e366676d92fb5e7ffbb7fdf493 test50:3.tiff
96d82681cf9a24452d5a63ce2044f5184d9686e366676d92fb5e7ffbb7fdf493 test50:4.tiff
96d82681cf9a24452d5a63ce2044f5184d9686e366676d92fb5e7ffbb7fdf493 test50:5.tiff
But even this isn’t going to be absolutely 100% guaranteed. So here’s my recommendation: Don’t take a sha256 of the result; instead, take a sha256 of the input, and annotate that with the changes made. So store a nice usable PNG file, but instead of storing its own hash, store something like this:
2aa4fa20701cdd6d8d56046069001186b5267e3ee7d0ef618ad2f4a683723e11-resize:50x50
This is absolutely guaranteed to be semantically correct, but it doesn’t specify a precise bit pattern. In HTTP terms, this is what would be called a “weak Etag” rather than a “strong Etag”. A web browser will happily retain its cached version of an object, knowing that it’s semantically equivalent to whatever it could fetch.
Would that be suitable for your purposes?