I eventually find the reason... It was a little tricky and Twitter didn't say anything about it in any docs, which is ....
You need to set the Content-Type
of the image correctly.
In my situation, I used Amazon S3 and Cloudfront for image storage. When I uploaded the images to S3, I didn't set the MIME type so S3 used application/octet-stream
as the default value. In this case, the images could be shown in an img
tag correctly, but would not be treated as an image by Twitter bot.
So I just reset the Content-Type of all the images to 'image/png' (or whatever they should be) and everything was all good.
P.S. Also make sure that you have your robot.txt
allow Twitterbot
to access.