Just scan from top to bottom left and right to get y top, and a similar algorithm with different directions for the rest.
Edit by Phrogz:
The pseudo-code implementation is implemented here. The included optimization ensures that each scan line does not look at pixels covered by an earlier pass:
function boundingBox() w = getWidth()
The result (in practice) performs roughly the same as the brute force algorithm for one pixel, and is much better as the object grows.
For fun, here is a visual representation of how this algorithm works:





It doesn't matter in which order you choose the sides, you just need to make sure that you take into account the previous results so that you don't look at the corners twice.
source share