Makale Özeti

Grafiksel öğelerin hızla geliştiği şu günlerde, yazılan programların işlevselliğinden çok aslında nekadar hoş gözüktüğü ve göze nekadar hitab ettiği artık daha önemli bir duruma gelir oldu. Bu acizane görüşüme katılan veya katılmayanlar tabiî ki olucak tır fakat bir gerçekle karşı karşıyayız artık gün grafik destekli programların günüdür. İş böyle iken aslına bakacak olursak client tarafında çalışan Windows programlarınında eskisi kadar raabet görmediği ortada . karşımızda dev bilgi kaynağı internet varken artık istemci tarafında çalışan uygulamarın pek tercih edilmediğii ve kullanım açısındada sadece bir internet tarayıcısının yeterli olduğu koskocaman canlı organizma yada organik bir salgın gibi yayılan web. peki bu organizmayı oluşturan dokular yani web sayfalarında kullanılan bir teknikten yada bir teknoljiden sizlere bahsedicem.

Makale

GDI+ Ile web de “Konsantre“ Grafik oluşturma

Grafiksel öğelerin hızla geliştiği şu günlerde, yazılan programların işlevselliğinden çok aslında nekadar hoş gözüktüğü ve göze nekadar hitab ettiği artık daha önemli bir duruma gelir oldu. Bu acizane görüşüme katılan veya katılmayanlar tabiî ki olucak tır fakat bir gerçekle karşı karşıyayız artık gün grafik destekli programların günüdür.

İş böyle iken aslına bakacak olursak client tarafında çalışan Windows programlarınında eskisi kadar raabet görmediği ortada . karşımızda dev bilgi kaynağı internet varken artık istemci tarafında çalışan uygulamarın pek tercih edilmediğii ve kullanım açısındada sadece bir internet tarayıcısının yeterli olduğu koskocaman canlı organizma yada organik bir salgın gibi yayılan web. peki bu organizmayı oluşturan dokular yani web sayfalarında kullanılan bir teknikten yada bir teknoljiden sizlere bahsedicem.

Uzun zamandır bir web sayfasında resim göstermek sıradan saydığız bir iştir aslında , yakın zamana kadar bende PATH yöntemini kullanarak resimlerimi sayfalarda yayınlıyordum fakat iş artık 2 milyonluk bir web sayfasını oluşturmaya gelip dayanınca ve bu ikimilyon resimlik sitenin ticari kaygıları ve yatırım sınırları varsa o zaman işler daha da karışmaya başlıyor. Lafı daha fazla uzatmadan sizlere kullandığım telkniği aktarmak istiyorum.

Öncelikle problemden başlamalıyım
  • elimizde 2 milyon adet resim var ve bu iki milyon resim günde yaklaşık olarak 600 MB lık bir upload miktarıyla karşı karşıya.
  • 500 GB diskimiz var ve yaklaşık 1 yıl bize yetmeli.
  • site içinde tam 4 boyda resim göstirimi yapılmakta ve en yüksek çözünürlüğe sahip resimler saklanmak zorunda.
Konvansiyonel yöntemlerle çözüm.

Yüklenen her resim için uygun boyutlarda Thumbnail resimler kesilip bunlar saklamalı ve yüksek çözünürlüğündeki resimler bir file server’e aktarılmalı. Gayet makul gibi . ama işimizi göremiyor.

Benim önerim sadece yüksek çözünürlükteki en kaliteli haldeki resimler saklanmalı ve bunların istenilen yerlerde istenilen boyutlarda runtime da Thumbnail leri alınarak herhangi bir yere kayıt edilmeden gösterilmeli.

Bu çözüm ile yaklaşık 100 GB lık Thumbnail dataların saklanacağı yerden kazanç sağlamaktayız ve disk maliyetimiz en az 3 ay lık bir kazanç sağlamakta.

Peki bunu nasıl yaparız. Bunu bize sağlayacak .net tabanlı en uygun çözüm GDI+ kullanmak olucaktır. Şimdi sizlere bunu GDI + ile nasıl yapabileceğimiz hakkında bir örnek yapıcam ve bu örnek ile bir çok şey anlatmaya çalışıcam.

Temel anlamda bir grafik web sayfasında göstermek için onun PATH ini yazabiliriz

<asp:Image ID="Image1" runat="server" ImageUrl="Images/KucukResim.jpg " Height="125px" Width="138px"  /> 

Şekilde olduğu gibi . fakat bu gösterim bize basiyt olarak kaynak resimi herhangi bir deformasyona uğratmadan getirecektir. Şimdi bu resimin biraz boyutlarıyla oynayalım .  bu işi bizim için yapan bir class hazırlayalım ve resimin her oluşacağı yerde bu class ı kullanarak resmi oluşturmaya çalışalım.

İlk olarak resimin bütününü görmak açısından  solution browserin ekran çıktısını vermek isterim..



Resimlerin depolandığı yerin bilgisinin tutlduğu bir tablo.

TableName=Tbl_ImagesData

Pratik olması açısından connectoion class ını ayrı yaratıyorum.

public class conn
{
SqlConnection _conn = new SqlConnection("Server=.;Database=MyImagesData;Trusted_Connection=True;");

    public SqlConnection Conn
    {
        get { return _conn; }
    }
}

 

Depolanan yüksek çözünürlük teki resimlerin depformasyon a uğratıldığı class.

Classname=GDI.cs
…        
using System.Data;
using System.Drawing;
using System.Data.SqlClient;
public class GDI
{
    public static System.Drawing.Image Get_KucukResim(int ImagesID) {
        conn c=new conn();
        System.Drawing.Image OrgImg,SmallImg;
        System.IntPtr inp = new IntPtr();
        string FullPath,RootPath,FileName,Query;
        int Width = 0;
        int Height = 0;

        Query = "SELECT * FROM Tbl_ImagesData Where ImagesID=" + ImagesID;
        SqlDataAdapter adp = new SqlDataAdapter(Query,c.Conn);
        DataTable dt = new DataTable();
        adp.Fill(dt);

        RootPath = dt.Rows[0]["Path"].ToString();
        FileName = dt.Rows[0]["FileName"].ToString();
        FullPath = RootPath + "\\" + FileName + ".jpg";
        try
        {
         
            OrgImg = System.Drawing.Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + FullPath);

        }
        catch (Exception)
        {
            OrgImg = System.Drawing.Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "Images\\Abort.jpg");
          
        }

        Width = 75;
        Height = 75;
        SmallImg = OrgImg.GetThumbnailImage(Width, Height, null, inp);
        return SmallImg;
    }

}

Yukarıda yazmış olduğumuz kodparçasında yapılanları gözden gerirelim. Öncelikle depolanma bilgisi Ado.net ile bulunduğu veritabanından alınarak alınıyor , bu bilgi bize resmin fiziksel olarak depolandığı yerin bilgisini veriyor. “System.Drawing.Image” tipinde bir images class ı yaratıyoruz. Bu class abstrak olduğundan dolayı doğrudan kullanmak zorundayım çünki bir instance si yaratılamıyor.[Bkz:what is the Abstrac class?] bu class ın içinde bulunan üyeleri kullanarak resmimi şekillen diriyorum [Bkz:Abstrac class Member]

FromFile method u benden bir string tipinde bir dosya yolu beklemektedir bu nu sağaya bilmek için ado.net ile adığım depolanma bilgisi method a yolluyorum. Class içeisinde artık içlemime devam etmek için bu şekilde fromfile diyerek (benim deyişimle grafiği bir konsantre haline çeviriyorum) konsantre haldeki resimin rahatlıkla Thumbnail ini GDI+ tarafından alıp bunu kullanabilirim. Yukarıda bahsettiğin konsanter kelimesi tamamen benim kendi uydurmamdır. Bu şekilde zaten çok fazla soyut olan bu iş biraz olsun sımutlaştırmış oluyorum.

GetThumbnailImage methodu benden bir konsanter halde bir images beklemektedir ve genişlik ve yüksekliğini göstermek istediğim kadar veriyorum. Böylece istenilen boyutlarda konsanter halde bir smallImages elde etmiş oldum.

Burada artık elimde küçültülmiş halde bulunan bir konsanter smallImages var bu gerçekte aslında yoktur runtime da makinanın RAM lerinde oluşmuştur ve bunu web sayfama aktarmak durumundayım . tabiki bu şekilde süper ortamda beklettiğimiz konsanreyi normalyollarla sayfamızda gösteremeyiz bu iş için pratik bir çevrim kullanmak durumundayım.

WebformName=createImage.aspx

public partial class CreateImage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.ContentType = "images/jpeg";
        int FotoID = Convert.ToInt32(Request.QueryString["ImagesID"]);
        System.Drawing.Image Thumb = GDI.Get_KucukResim(FotoID);
        Thumb.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
        Thumb.Dispose();

    }
}

Ihtiyaç duyulduğunda resmin oluşturulması için (ContentType = "images/jpeg") olan bir sayfa yaratmak durumundayım. Dikkat edilirse oluşturduğum class içinde bulunan function u yada method u burada bir instancesini çıkarmadan kullana bilmek için static olarak yarttım ki herseferinde  yada her resim için çalıştırılması gerekli.[Bkz:Access Modifier]. Tabiki bu konsanterden yine süper bir ortamda saklanmalı bu sebeple binary şeklinde bir body formatıyla RAM lerimin içinde kayıt işlemi yapıyorum. En son satıra dikkat edilirse kayıt şlemi tamamlandıktan sonra bu konsantereyi ortadan kaldırmam gerekiyor.

Son olarak resmin gösterilmesini istediğim sayfada resmin ID sini bu createImage.aspx sayfasına yolluyorum bu işlem için URL Parametresi yöntemi en hızlı gönderim methodu olduğunu düşüyorum.

Default.aspx sayfası

Bir datalist sürükleyip bırakıyorum ve adınada DtlPhotos diyorum. Sergilemek istediğim resimlerin hangileri ise bunu ado.net yardımıyla ilgli kaynaktan istiyorum ve aşşağıdada görüldüğü üzere  bir adapter kullanarak datalist in  kaynağına dolduruyorum.

 

public partial class _Default : System.Web.UI.Page
{
    SqlConnection conn = new SqlConnection("Server=.;Database=MyImagesData;Trusted_Connection=True;");
    protected void Page_Load(object sender, EventArgs e)
    {

        if (!Page.IsPostBack) Fillimages();

    }

void Fillimages(){
       conn c=new conn();
       string Quary = "Select * from Tbl_ImagesData";
       SqlDataAdapter adp = new SqlDataAdapter(Quary,c.Conn);
       DataTable dt = new DataTable();
       adp.Fill(dt);

       DtlPhotos.DataSource = dt;
       DtlPhotos.DataKeyField = " ImagesID";
       DtlPhotos.DataBind();
   }

Bu şekilde doldurduğum datalist in her bir Item i oluşurken yada daha anlaşılır bir ifadeyle içinde kullandığım her bir Images nesnesi yada form kontrolu oluşurken gidip createImages.aspx sayfasına bu parametreleri URL yöntemiyle yollayarak resimlerin önbellekte oluşmasını sağlamaya çalışıyorum.

Default.aspx sayfasının source kodlarıda aşşağıda sergilenmektedir.

<body>
    <form id="form1" runat="server">
        <asp:DataList ID="DtlPhotos" runat="server">
            <ItemTemplate>
                <asp:Image ID="ImgPhoto" runat="server" ImageUrl='<%# "CreateImages.aspx?FotoID=" + Eval("ImagesID") %>' />
            </ItemTemplate>
        </asp:DataList>
    </form>
</body>

Sonuç olarak. Dinamik olarak oluşan resimler elde etmiş olduk ama ortada aslında küçük bir resim felan da yok. konsantre var….


Önemli bir kazanımlardan biride. Kaynak adres gizlenmiş olmak tadır. Örneğin 1 numaralı resim için properties bilgisi.

umarım pratik kullanım alanı bulunan bir yöntem olur sizin için.