如何在数据库中存储图像

时间:2013-08-05 18:28:36

标签: mysql perl

我正在尝试在数据库中插入图像。数据库有一个名为images的字段,其类型为BLOB。我试图插入图像,但只存储了第一个2.2KB。即使我插入另一个图像,它只在数据库中存储2.2KB。

当我尝试在我的应用程序中显示此图像时,它没有显示;它只是一个小图标,而不是图像。如何以正确的方式插入图像?

use CGI;  
my $file = $q->param("file"); 
$file = 'C:/wamp/bin/apache/apache2.2.22/cgi-bin/images/2.jpg';
open(my $fh, $file);
my $data;
binmode($fh);
read($fh, $data, (stat($fh))[7]);
close($fh);

my $Data = {
        table    =>'student',
        data     => {    
        Image    => $fh,
        }       
};

Data::Insert($Data);

print $q->header;
print $q->start_html(
   -title => "student",
);

print $q->end_html;

showImage.pl

my $q = new CGI();
my $handle = Dbm::connection();

$id = $q->param('id_person');

$getimage = $handle->selectrow_array (<<SQLEOF); 
    SELECT Image
      FROM student  
    WHERE ID  = '$id'
SQLEOF

print "Content-Type: image/jpeg\n";
print "Content-length: \n\n";

binmode STDOUT;
print STDOUT $getimage;

3 个答案:

答案 0 :(得分:1)

我的推荐是将图像作为基础64加密到具有图像MIME类型的数据库。当你需要它时,只需通过说MIME类型来解密它。这主要用于使用ajax上传文件。那么为什么我们不能使用相同的方式将图像直接存储到DB?

只需添加一个列以保留表中的MIME类型,并将其与编码数据一起打印在一起。

从文件扩展名中,我们可以识别文件的类型。图像的MIME类型主要是

image/gif: GIF image
image/jpeg: JPEG JFIF image;
image/pjpeg: JPEG JFIF image; 
image/png: Portable Network Graphics;
image/svg+xml: SVG vector image;
image/tiff: Tag Image File Format (only for Baseline TIFF);

您可以通过将名称命名为mime_typ来创建新列。现在,当您使用base 64加密来封装文件时,请将其保存为字符串,就像我们将用户名和密码存储在表中一样。同样,将MIME type添加到mime_typ列。如果要显示图像,请在解码后将加密内容与MIME类型中的内容一起打印,该内容存储在mime_typ列的同一行中。 You can search google for the way to show an image which is encrypted in base 64 encryption.

答案 1 :(得分:0)

您需要以二进制模式读取文件 - 即

open(my $fh, $myfile);
my $data;
binmode($fh);
read($fh, $data, (stat($fh))[7]);
close($fh);

答案 2 :(得分:0)

我不确定为什么你从问题中删除了数据库插入代码,但我在revision history中找到了它。

问题可能是因为您没有使用绑定变量,并且二进制图像包含导致问题的转义字符。

我建议使用DBIx::Simple来帮助创建有助于为您创建绑定变量的insert语句。 DBIx :: Simple适用于SQL :: Abstract和SQL :: Interp。我发现SQL :: Interp更灵活。

您将文件句柄插入图像字段而不是文件数据似乎也是一个错误。尝试添加use File::Slurp(您可能需要安装),然后将其放入%data哈希:

 Image    =>  scalar read_file($file, { binmode => ':raw' });

您的SELECT语句也容易受到SQL注入攻击,因为您在将外部输入传递给数据库之前未对其进行验证,并且您没有再次绑定变量。使用DBIx::Simple,相同的代码如下所示:

my $db = DBIx::Simple->new($handle);
$getimage = $db->iquery("SELECT Image FROM student WHERE ID  = ",\$id)->list;

另外,我建议省略Content-Length标头,或正确计算它,而不是让它存在无效状态。