I’ve got an issue with a website I’m working on, and I’m not getting much luck finding a solution via the hardcore programming boards, so I thought I’d throw it out here to a wider audience in hopes that someone might have some great ideas.
For this particular website, we allow users to upload images and later on, retrieve & display them on a web page. We don’t store them on the web server as an image file, instead, we store them in a database. That’s about the only semi-funky thing we do.
When the user wants to see the image they’ve uploaded, we run out to the DB, grab the image, and stream it back to the website. All is good; everything works for .jpg, .gif, and .png types of images.
Bitmaps, however, are goofy. They don’t show up as the bitmap itself, instead, they show up as a black square of whatever size the bitmap is. So if I uploaded a 100x300 pixel bitmap, I see a 100x300 pixel black square.
The code that all these various types go through is virtually identical. The only real difference is that when we retrieve the file, we determine which type it is and set the content type to image/gif or image/png or whatever.
I first thought that maybe the bitmaps were not being stored correctly, so I tried retrieving them from the DB and storing them as a file on disk. That works great - the image I store on disk is the same as the uploaded image. So I don’t think the issue is a DB issue.
Anyone got any great ideas on this one? I have to admit, I’m sort of stumped. The code looks fine; the stored image seems fine. Everything works for all types of images except bitmaps. WTH?!?
Someone who knows better can explain, but what is the source of these images? E.g. clarify “we run out to the DB, grab the image, and stream it back to the website.” Are they screenshots (Printscreen) from a transient source like a video window?
The reason why I ask: in the past I could Printscreen a video and paste into Paint etc. It would show up fine and I could save it. But if I later closed the video program and reopen the image, it would be black.
They’re not screenshots. We’ve tried all sorts of bitmaps, including just opening MS Paint and drawing a circle and saving it as a bitmap. It doesn’t seem related to the file itself.
Does the image display if you just drag the file into your browser window, instead of sending it via your web system?
I do not think .bmp files have traditionally been included in web standards (presumably because they are not compressed and thus can be pretty large, which was a problem back in the dial-up days), although most browsers will, in fact display them. I just tried dragging some .bmp files into Firefox, IE, Chrome and Safari, and they all displayed normally.
Oh yeah? For every “Best Practice” site that says to store 'em on the file system there’s another one that says to store 'em in the DB. Doesn’t really matter to me either way, but the DB is what we decided on long ago for this website so we’re stuck with it for now.
The original. Edit: wait, I read that wrong. I’ll test it tomorrow and let you know (walking out right now).
The original.
Everything works except displaying it directly from the DB. Displaying directly from the DB work for all types except bitmaps. Confounding.
Unfortunate. I’m not sure who gave you that advice, but now you’re stuck with a site you can’t serve from a CDN, like Akamai or Amazon S3. That’ll be a super-expensive retrofit if your traffic grows.
Sorry, I don’t have a solution for your BMP problem.
No. They’re simple caches. S3 is roughly equivalent to a basic filesystem. Blakeyrat is right, your architecture is limiting.
I’ve seen oddities with browser handling of certain types of BMP files (odd colour depth etc). There were some versions of IE that didn’t correctly handle certain types of bitmapped images (PNGs with certain features), it’s possible the same bug caused had issues with BMP files too. But it’s unlikely those are causing your problems.
Far more likely it’s that you’re serving them up wrong - incorrect HTTP headers, leading or trailing junk, incorrect handling of binary data, something like that. If you’re going to roll your own handler for serving images, you need to test it carefully in isolation.
Yeah, I know, I’ve worked with Akamai before, and am familiar with Amazon S3. It was a stupid comment on my part because I got a little annoyed that the thread turned from trying to fix this problem that I’ve been banging my head against for a few hours now from the issue itself to whether or not storing images in the DB was smart or dumb.
But we’re all making assumptions here. Trust me, with this website, there’s no way that storing these images in the DB versus the file system makes any difference at all. That issue is completely inconsequential; I just want to fix the problem at hand.
What code are you using to display the image? Sounds like maybe an error on that end?
We use a prefab C# ecomm app called NOP Commerce and it stores all of the images in the db. When you call an image it actually builds a new re-sampled version of it based on the size you specified and saves an actual file to a thumbnails directory and then serves up the file it just created. Obviously, there’s a system in place to know whether to find a file it already created or to make a new one. There’s not just a million files.
Another thing you could try is a converter that converts your BMP to GIF, basically disallowing BMPs in the database. That is if file type doesn’t matter and you have access to the upload part.
Is the bitmap stored in a blob as a perfect, byte-by-byte copy of a .BMP file, or is there a translation? Does the server try to extract any metadata from the blob (size, bit depth, scan direction) when serving it out?
As far as I know, that’s not really correct. If the CDN is acting as a true cache, it shouldn’t actually matter as long as the cache directives are specified correctly. In fact, it should be totally invisible externally whether the image data comes from a database, a file system, or is even simply generated programmatically.
Could be that - if the images are in a BLOB field, there are different flavours for that. Might be worth trying it with a really small (say 8x8) bitmap, and/or scrutinising the field type.
Or it could be some mismatch between the way the DB is expressing binary/byte data, and the way the web server is expecting to receive it. Big vs Small-endian or binary vs ANSI or something.
Yeah, thought of that, already tried the “really small” idea. For the record, none of these images are large - I think it restricts them to 125x300 pixels or something equally tiny.
This what I suspect, but haven’t been able to track it down yet. <sigh> I think I’m gonna have to resort to examining the byte streams.