If I were making images often, I would not want to be shrinking and regrowing my SD card partition repeatedly.
I'd want to leave the partition big, because this is better for the card and more efficient for the system, but create minimal size images. To do this, figure out what size you'll need (see
man df) and, on a (linux) computer separate from the pi, create an empty file of that size:
dd if=/dev/zero of=filesystem.img bs=512 count=4194304
That's a 2GB image (512 bytes * 4194304 = 2147483648 bytes = 1024 * 1024 * 1024 * 2). Here's an interesting thing: you can make a filesystem in the (empty) file.
Don't worry about the "this is not a block device" warning. Now create a mount point and mount it:
mount filesystem.img fsmnt
Now there's an empty ext4 filesystem mounted on fsmnt (there will be one "lost+found" directory, which is basic to ext filesystems; notice there is one on the pi).
You can now copy everything from the SD card partition in. This means there is zero wear on and zero risk for the card. Then just umount the image:
Guess what? Everything you copied into the mount point is now in filesystem.img, which can be used exactly the same way you used the original raspbian (or whatever) image (and this is almost certainly how they make those).