메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

ASP.NET에서 이미지를 데이터베이스에 저장하기

한빛미디어

|

2006-12-27

|

by HANBIT

23,638

제공: 한빛 네트워크
저자: 한동훈

웹 프로그램을 작성할 때, 이미지는 파일로 저장하는 것이 가장 효율적이지만, 상품 이미지와 같이 이미지를 지속적으로 사용하는 경우에 삭제된 이미지, 누락된 이미지를 관리하는 것이 어려워지기 때문에 이미지를 데이터베이스 저장하는 것을 고려하게 됩니다. 이미지를 데이터베이스에 저장하게 되면 관리는 쉬워지지만, 이미지를 불러오는 부하가 증가한다는 단점이 있습니다. 모든 것에는 장점이 있으면 단점도 있는 법이지요.

이번에는 ASP.NET에서 이미지를 데이터베이스에 저장하는 방법을 설명합니다. 먼저, 응용프로그램에서 사용할 테이블을 다음과 같이 정의합니다.

그림1

IDX 열은 자동으로 증가하는 값으로 IDENTITY( 1, 1)로 설정하며, 기본키로 설정합니다. FileName 열은 이미지의 파일명을 저장하기 위해 사용합니다. 이미지를 데이터베이스에 저장하게 되면 이미지의 파일이름이 사라지기 때문에 원래의 파일 이름을 저장할 필요가 있습니다. 이미지를 파일로 저장하는 경우에는 같은 파일이름이 있는지 검사하고, 같은 파일이름이 있으면 파일 이름을 적절하게 변경하는 코드가 필요하지만, 데이터베이스에 저장할 때는 파일 이름이 같아도 문제가 되지 않습니다. Nvarchar 타입으로 지정합니다. Nvarchar는 유니코드 가변 문자열을 저장하기 위해 사용합니다. Image열은 image 타입으로 지정합니다. 이는 바이너리 파일을 저장하기 위해 사용하며 최대 크기는 4G입니다. Image 열은 DB 페이지가 아닌 별도의 페이지에 저장됩니다.

이미지를 업로드하는 저장 프로시저를 작성합니다. 저장 프로시저의 이름은 InsertImage입니다.
CREATE PROCEDURE InsertImage
  @FileName nvarchar(250),
  @Image image,
  @Idx int output
AS
BEGIN

  SET NOCOUNT ON;

  INSERT INTO pictures( FileName, Image )
    VALUES ( @FileName, @Image )
  
  SELECT @idx = SCOPE_IDENTITY();
END
GO
저장 프로시저를 작성했으면 새로운 ASP.NET 프로젝트를 생성합니다. 여기서는 비주얼 스튜디오 2005를 사용하며, ASP.NET 2.0을 사용합니다. 실제로는 ASP.NET 1.1로 해도 큰 차이는 없습니다. 새로운 ASP.NET 페이지 이름은 Upload.aspx로 하고, 다음과 같이 FileUpload 컨트롤과 Button 컨트롤을 배치합니다. 컨트롤의 이름은 각각 fuControl, btnUpload로 설정합니다.

그림2

버튼을 클릭했을 때 실행되는 이벤트 코드를 작성합니다. 여기서는 btnUpload_Click() 함수로 이벤트 처리 코드를 작성합니다. 전체 코드는 다음과 같습니다.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.Data.SqlClient;
using System.IO;

public partial class _Default : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {

  }

  protected void btnUpload_Click(object sender, EventArgs e)
  {
    string fileName = fuControl.PostedFile.FileName;
    fileName = System.IO.Path.GetFileName(fileName);
    fileName = Server.HtmlEncode(fileName);

    int fileSize = fuControl.PostedFile.ContentLength;

    Stream stream = fuControl.FileContent;

    byte[] image = new byte[fuControl.PostedFile.ContentLength];
    stream.Read(image, 0, fuControl.PostedFile.ContentLength);
    stream.Close();

    SqlConnection sc = new SqlConnection(
      "Data Source=(local); Initial Catalog=pictures; Integrated Security=True;");

    SqlCommand scmd = new SqlCommand("InsertImage", sc);
    scmd.CommandType = CommandType.StoredProcedure;

    SqlParameter spIdx = new SqlParameter("@idx", SqlDbType.Int);
    spIdx.Direction = ParameterDirection.Output;

    SqlParameter spFilename = new SqlParameter("@FileName", SqlDbType.NVarChar, 250);
    spFilename.Value = fileName;

    SqlParameter spImage = new SqlParameter("@Image", SqlDbType.Image);
    spImage.Value = image;

    scmd.Parameters.Add(spIdx);
    scmd.Parameters.Add(spFilename);
    scmd.Parameters.Add(spImage);

    sc.Open();
    scmd.ExecuteNonQuery();
    sc.Close();

    int newIdx = (int)spIdx.Value;

    Response.Write("새로운 IDX는 " + newIdx.ToString() + "입니다");

    sc.Dispose();
    scmd.Dispose();

    Response.Redirect(Request.ServerVariables["SCRIPT_NAME"]);
  }
}
파일 업로드를 처리하기 위해 System.IO 네임스페이스를 추가하고, DB를 사용하기 위해 System.Data.SqlClient 네임스페이스를 추가합니다. 파일이름으로 사용할 수 있는 문자는 사용하는 운영체제 마다 다르며, #과 같이 웹에서 사용하기 적절하지 않은 문자가 포함될 수 있기 때문에 적절히 인코딩을 합니다. 업로드된 파일의 내용을 읽어오기 위해서는 바이트 수를 알아야하기 때문에 ContentLength 속성을 사용합니다. Image 타입으로 저장하기 위해서는 바이트 배열이어야 하므로 바이트 배열로 데이터를 읽어옵니다. 나머지는 ADO.NET에서 저장 프로시저를 사용해서 데이터를 저장하는 과정입니다.

웹 브라우저에서 이 코드를 테스트하면 파일이 제대로 업로드 되는 것을 알 수 있습니다.

그림3

이미지를 업로드하면 같은 화면을 다시 로딩하기 때문에 아무 변화가 없는 것처럼 보입니다. SQL Server에서 쿼리를 해보면 다음과 같이 이미지가 업로드 된 것을 알 수 있습니다.

그림4

다음에는 데이터베이스에서 이미지를 가져와서 화면에 출력하는 방법에 대해 설명하겠습니다.
TAG :
댓글 입력
자료실