resim kayıt sorun

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
erdogan_ozkaya
Üye
Mesajlar: 839
Kayıt: 03 Eki 2007 02:00

resim kayıt sorun

Mesaj gönderen erdogan_ozkaya »

Arkadaşlar,

Aşağıdaki kod ile Delphi7 de resim kayıt edip gösteriyorum bir sorun yok.

Fakat delphi xe8 de kaydediyorum (androidde) kaydettiğim veriyi aynı kodla delphi7 de gösteremiyorum hata veriyor.

verdiği hata " raised exception class ejpeg with message 'jpeg error #53' " hatayı da araştırdım ama bir sonuca varamadım

daha önce bir konusu olmuş denedim ama yine olmadı.
/forum/viewtopic.php?t=30507

SQL alan tipi "image"

save

Kod: Tümünü seç

procedure TDENETIM_ISLEM_PENCERE1.Button1Click(Sender: TObject);
 var
    AStream: TMemoryStream;
begin
      DENETIM_HAREKETLERI_DB.Insert;

        begin
         if NOKTA_RESMI_IMAGE1.Bitmap = nil
            then   else
            begin
              AStream := TMemoryStream.Create;
              try
                 NOKTA_RESMI_IMAGE1.Bitmap.SaveToStream(AStream);
                 AStream.Position := 0;
                  TBlobField(DENETIM_HAREKETLERI_DB.fieldByName('RESIM1')).LoadFromStream(AStream);

                finally
                AStream.Free;
              end;
             end;
             end;

      DENETIM_HAREKETLERI_DB.Post;
  end;

load

Kod: Tümünü seç

procedure TForm1.btn1Click(Sender: TObject);
var
jpeg: tjpegimage;
buf: tmemorystream;
begin

    IF QRY_1RESIM1.Value<>''
    THEN BEGIN
       jpeg := tjpegimage.create();
      buf := tmemorystream.create();
      QRY_1RESIM1.savetostream(buf);
      buf.seek(0, soFromBeginning);
      jpeg.loadfromstream(buf);
      img2.picture.assign(jpeg);
      buf.free;
      jpeg.Free;
     end;

end;
ertank
Kıdemli Üye
Mesajlar: 1716
Kayıt: 12 Eyl 2015 12:45

Re: resim kayıt sorun

Mesaj gönderen ertank »

Merhaba,

Aşağıdaki soruları cevaplayabilir misiniz?
1- SQL Server versiyonu nedir?
2- Örnek bir iki tane JPEG dosyası paylaşabilir misiniz?
3- Aşağıdaki testlerin sonuçlarını paylaşabilir misiniz?
3a- XE8 ile Windows ortamında resim kaydedip yine windows ortamında ekranda gösterebiliyor musunuz?
3b- Delphi 7 ile Windows ortamında kaydedip XE8 ile Windows ortamında ekranda gösterebiliyor musunuz?
3c- XE8 ile Windows ortamında resim kaydedip XE8 ile Android ortamında ekranda gösterebiliyor musunuz?

Bu sorular dışında:
A- "image" veri türünü kulanmayın. Bu veri türü ileriki SQL Server sürümlerinde kaldırılacak.
Kaynak: https://docs.microsoft.com/en-us/sql/t- ... ansact-sql
Ayrıca mevcut projeleriniz için ntext, text ve image veri türlerini dönüştürmeniz tavsiye edilmekte. Bu tavsiyeyi dinlemekte fayda var.

Resim dosyası veya herhangi bir dosya kaydetmek için varbinary(max) veri türünü kulanabilirsiniz.

B- Herhangi bir dosyayı database içine kaydeder iken mutlaka dosya ekini başka bir alan içinde saklayın. Siz jpeg olarak düşünebilirsiniz. Ancak png veya bmp türünde resim dosyası olabilir. Ya da pdf dosya değil xls dosya veya xlsx dosya türü olabilir. Kullanıcının ne yaptığını ve hata kaynağını bulmanız çok or olabilir. Dolayısıyla bu bilginin kaybolmaması gerekli.

Mümkünse uygulamanızı bu şekilde dönüştürün.
Lord_Ares
Üye
Mesajlar: 1070
Kayıt: 15 Eki 2006 04:33
Konum: Çorlu

Re: resim kayıt sorun

Mesaj gönderen Lord_Ares »

Bu arada dikkatimi çeken birşeyi de hatırlatmak istedim. Mümkün olduğunca değişken isimlerini sistem isimleri ile aynı vermemeye çalışın.
Mesela jpeg sistem tarafından kullanılıyor ise projelerinizde çözümü epey uğraştıracak sonuçlar doğurabilir. Mümkünse daha farklı tanımlayı isimleri kullanmanızı öneririm
erdogan_ozkaya
Üye
Mesajlar: 839
Kayıt: 03 Eki 2007 02:00

Re: resim kayıt sorun

Mesaj gönderen erdogan_ozkaya »

Merhaba,

1- SQL Server versiyonu nedir? - SQL 2012
2- Örnek bir iki tane JPEG dosyası paylaşabilir misiniz? - normal sıradan webde bulduğum herhangi bir resim.

3a- XE8 ile Windows ortamında resim kaydedip yine windows ortamında ekranda gösterebiliyor musunuz? - EVET

Windosta ex8 de kaydedip gösterebiliyorum - androidde de gösteriyor.

Kod: Tümünü seç

procedure THeaderFooterForm.Button2Click(Sender: TObject);
var
jpeg: TBitmap;
buf: tmemorystream;
begin

       jpeg := TBitmap.create();
      buf := tmemorystream.create();
      QRY_TESTRESIM6.savetostream(buf);
      buf.seek(0, soFromBeginning);
      jpeg.loadfromstream(buf);
      NOKTA_RESMI_IMAGE1.Bitmap.assign(jpeg);
      buf.free;
      jpeg.Free;

end;
3b- Delphi 7 ile Windows ortamında kaydedip XE8 ile Windows ortamında ekranda gösterebiliyor musunuz? - EVET

3c- XE8 ile Windows ortamında resim kaydedip XE8 ile Android ortamında ekranda gösterebiliyor musunuz? - EVET

ama xe8 de kaydettiğimi delphi7 de gösteremiyorum :(

bir türlü çözemedim.

not: dediğiniz gibi resim alanlarını varbinary(max) yaptım bilgi için teşekkür ederim.
erdogan_ozkaya
Üye
Mesajlar: 839
Kayıt: 03 Eki 2007 02:00

Re: resim kayıt sorun

Mesaj gönderen erdogan_ozkaya »

Merhaba,

not: resmimleri kameradan çekiyorum

jpeg error #53 sürekli bu hatayı veriyor :(

denediğim kodlar aşağıdaki gibi teşekkür ederim.

Kod: Tümünü seç

procedure TForm1.btn1Click(Sender: TObject);


var
jpeg: TBitmap;
buf: tmemorystream;
begin

       jpeg := TBitmap.create();
      buf := tmemorystream.create();
      QRY_1RESIM6.savetostream(buf);
      buf.seek(0, soFromBeginning);
      jpeg.loadfromstream(buf);
      img2.Picture.assign(jpeg);
      buf.free;
      jpeg.Free;


end;

procedure TForm1.btn2Click(Sender: TObject);
    var
   AStream: TMemoryStream;
begin

        AStream := TMemoryStream.Create;
        try
          if QRY_1.Active then
          begin
            TBlobField(QRY_1.FieldByName('RESIM6')).SaveToStream(AStream);
            AStream.Position := 0;
             img2.Picture.Graphic.LoadFromStream(AStream);
          end;
         finally
          AStream.Free;
         end;
  end;


procedure TForm1.btn3Click(Sender: TObject);
var
 MemStrm: TMemoryStream;
 Jpg:     TJPEGImage;
begin
  If QRY_1RESIM6.IsNull then
   begin
     img2.Picture.Assign(nil);
     Abort;
   end;
   Jpg:=TJPEGImage.Create;
   try
    MemStrm:=TMemoryStream.Create;
    try
      QRY_1RESIM6.SaveToStream(MemStrm);
      MemStrm.Seek(0,soFromBeginning);
      with Jpg do
      begin
        PixelFormat:=jf24Bit;
        Scale:=jsEighth;
        GrayScale:=False;
        Performance:=jpBestQuality;
        ProgressiveDisplay:=True;
        ProgressiveEncoding:=True;
        LoadFromStream(MemStrm);
      end;
      img2.Picture.Assign(Jpg);
    finally
     MemStrm.Free;
    end;
   finally
    Jpg.Free;
   end;
  // TBlobField(QRY_1.FieldByName('RESIM6')).SaveToStream(S);


end;
ertank
Kıdemli Üye
Mesajlar: 1716
Kayıt: 12 Eyl 2015 12:45

Re: resim kayıt sorun

Mesaj gönderen ertank »

Firemonkey platformu ile VCL platformu arasında resim işleme anlamında ciddi farklılıklar vardır. Firemonkey platformu sadece TBitmap üzerinden işlem yapar. Ancak, VCL platformunda TGraphics üzerinden türeyen TBitmap, TJpeg, TPngImage gibi formatlar vardır.
Detaylı bilgi için: http://docwiki.embarcadero.com/Librarie ... decManager

Bu bazı sorunlara yol açabilmektedir. Şöyle ki; Firemonkey platformuında resim dosyası saklamak için dosya eki resim içinde kullanılacak codec (sıkıştırma formatı) için belirleyici olur. Ancak VCL ortamında hangi format saklanacak/okunacak ise o formata uygun bileşen ile saklamak/okumak gerekir.

Siz Android ortamında resimi stream üzerinden kaydeder iken dosya eki belirtmediğiniz için yüksek ihtimalle resim bmp formatında saklanıyor olmalı. Delphi 7 ile jpeg türünde açmaya çalıştığınız zaman da sorun ile karşılaşıyorsunuz.

Bunu doğrulamak için Android üzerinden kaydedilmiş birkaç resim dosyasını database içinden diske kaydederek dosyanın ilk byte değerlerine bakabilirsiniz.
Bitmap $42 $4D ile başlar.
Jpeg $FF $D8 $FF $E0 ile başlar
Png $89 $50 $4E $47 $0D $0A $1A $0A ile başlar.
Detaylı bilgi için: https://en.wikipedia.org/wiki/List_of_file_signatures

Android platformunda resimi database içine stream üzerinden jpeg formatına kaydetmek için aşağıdaki yardımcı fonksiyonu kullanabilirsiniz.

Kod: Tümünü seç

uses
  FMX.Graphics, FMX.Surfaces, FMX.Types, FMX.Consts;

procedure SaveJpegToStream(Bitmap: TBitmap; Stream: TStream);
var
  Surf: TBitmapSurface;
  Params: TBitmapCodecSaveParams;
begin
  Params.Quality := 95;

  Surf := TBitmapSurface.Create;
  try
    Surf.Assign(Bitmap);
    if not TBitmapCodecManager.SaveToStream(Stream, Surf, '.jpg', @Params) then
      raise EBitmapSavingFailed.Create(SBitmapSavingFailed);
  finally
    Surf.Free;
  end;
end;
Kullanımı aşağıdaki gibi olacaktır:

Kod: Tümünü seç

var
  Stream: TMemoryStream;
begin
  if not QRY_1.Active then Exit();
  
  Stream := TMemoryStream.Create();
  try
    SaveJpegToStream(NOKTA_RESMI_IMAGE1.Bitmap, Stream);
    TBlobField(QRY_1.FieldByName('RESIM6')).LoadFromStream(Stream);
  finally
    Stream.Free();
  end;
end;
Yukarıdaki şekilde kullanım ile Android ortamında database içine her zaman jpeg formatında veri kaydettiğiniz için VCL ortamında database içinden aşağıdaki şekilde okuyarak ekranda gösteriyor olmanız gerekli.

Kod: Tümünü seç

var
  Jpeg: TJpegImage;
  Stream: TMemoryStream;
begin
  if TBlobField(QRY_1.FieldByName('RESIM6')).IsNull then
  begin
    Img2.Picture.Assign(nil);
    Exit();
  end;
  
  Jpeg := TJpegImage.Create();
  try
    Stream := TMemoryStream.Create();
    try
      TBlobField(QRY_1.FieldByName('RESIM6')).SaveToStream(Stream);
      Stream.Position := 0;
      Jpeg.LoadFromStream(Stream);
      Img2.Picture.Assign(Jpeg);
    finally
      Stream.Free();
    end;
  finally
    Jpeg.Free();
  end;
end;
Son olarak:
- Yazdığınız kod içinde hafıza kaçağı ihtimali olan çok fazla satır var. Bu konuya dikkat etmenizi öneririm.
- Değişken isimlerini mümkün mertebe Pascal usulüne uygun şekilde yazmanızı öneririm.
- Blok (begin..end, try..finally..end) arasındaki içerleme karakterlerinizin sayısı standart olarak 2 veya 4 değil. Farklı farklı. Bu yazdığınız kodun okunabilirliğini zorlaştırıyor. Bu konuya dikkat etmenizi öneririm.
- Gerek olmadığı halde boş satırlar bırakmışsınız. Bu konuya da dikkat etmenizi öneririm.
- Abort Delphi içinde sessiz bir Exception oluşturur. Mevcut prosedür, fonksiyon içinden çıkmak için Exit() kullanmalısınız. Abort kullanımını Database içine veri kayıt kontrolünde OnBeforeInsert() gibi olayların içinde kullanmayı tercih etmeniz daha doğru olacaktır.
- Mümkün mertebe "with" kullanımından kaçının. Kod okuma ve yazma karışıklığına sebep verebilir. with ile kullanmak istediğiniz nesne parametresine değil formun başka bir parametresine atama yapma ihtimaliniz vardır.
erdogan_ozkaya
Üye
Mesajlar: 839
Kayıt: 03 Eki 2007 02:00

Re: resim kayıt sorun

Mesaj gönderen erdogan_ozkaya »

Cevabınız ve bilgilendirmeniz için Çok Teşekkür ederim. söylediğiniz gibi kodlar çalışıyor.
erdogan_ozkaya
Üye
Mesajlar: 839
Kayıt: 03 Eki 2007 02:00

Re: resim kayıt sorun

Mesaj gönderen erdogan_ozkaya »

Hocam son bir soru,


eğer resim seçip kayıt yaparsam sorun yok gösteriyor da ama verdiğiniz kodu kullandığımda delphi7 de kayıt yapamıyorum (kamera kullanıyorum)


çapraz kayıt yapıp ve gösterdiğim için aşağıdaki kodu delphi7 de nasıl yapabilirim ?



bu kısım delphi7 de nasıl yapabiliri ?

Kod: Tümünü seç

uses
  FMX.Graphics, FMX.Surfaces, FMX.Types, FMX.Consts;

procedure SaveJpegToStream(Bitmap: TBitmap; Stream: TStream);
var
  Surf: TBitmapSurface;
  Params: TBitmapCodecSaveParams;
begin
  Params.Quality := 95;

  Surf := TBitmapSurface.Create;
  try
    Surf.Assign(Bitmap);
    if not TBitmapCodecManager.SaveToStream(Stream, Surf, '.jpg', @Params) then
      raise EBitmapSavingFailed.Create(SBitmapSavingFailed);
  finally
    Surf.Free;
  end;
end;

göstermek için

Kod: Tümünü seç

var
  Stream: TMemoryStream;
begin
  if not QRY_1.Active then Exit();
  
  Stream := TMemoryStream.Create();
  try
    SaveJpegToStream(NOKTA_RESMI_IMAGE1.Bitmap, Stream);
    TBlobField(QRY_1.FieldByName('RESIM6')).LoadFromStream(Stream);
  finally
    Stream.Free();
  end;
end;
ertank
Kıdemli Üye
Mesajlar: 1716
Kayıt: 12 Eyl 2015 12:45

Re: resim kayıt sorun

Mesaj gönderen ertank »

Öncelikle Delphi XE8 kullanabiliyor iken neden hala Delphi 7 ile proje geliştiriyosunuz? Eski projelerinizi XE8'e çevirmenin zamanı çoktan geçti.

1- Paylaştığınız kod örnekleri XE8 Firemonkey framework içindir. Delphi 7 altında bu kodları derleyemezsiniz.
2- Diğer taraftan "Delphi 7'de kayıt yapamıyorum" derken ne anlatmak istediğinizi bilemiyorum. Hangi kod için bu ifadeyi kullandınız? Hata mesajı mı alıyorsunuz? Daha detaylı şekilde ifade edebilir misiniz?
3- Gönderdiğiniz kodların her ikisi de database'e resim kaydetmek için. Siz ikincisine göstermek için yazmışsınız ancak bu kodda kayıt için.
4- Benim ilk sorunuzdan anladığım Android ortamında kaydedip Delphi 7 ile göstermek istiyorsunuz şeklinde idi. Şimdi sorduğunuzdan hem Android ortamında kaydetmek, hem Delphi 7 ortamında kaydetmek ve ayrıca Delphi 7 ortamında ekranda göstermek istediğinizi anlıyorum.

Bir önceki cevabımda zaten VCL kısmında (Delphi 7 veya Delphi XE8) nasıl ekranda göstermek gerektiği ile ilgili örnek kod paylaşmıştım. Muhtemelen gözünüzden kaçtı. Kolaylık olması açısından tekrar bu mesaj içine kopyalıyorum.

Kod: Tümünü seç

var
  Jpeg: TJpegImage;
  Stream: TMemoryStream;
begin
  if TBlobField(QRY_1.FieldByName('RESIM6')).IsNull then
  begin
    Img2.Picture.Assign(nil);
    Exit();
  end;
  
  Jpeg := TJpegImage.Create();
  try
    Stream := TMemoryStream.Create();
    try
      TBlobField(QRY_1.FieldByName('RESIM6')).SaveToStream(Stream);
      Stream.Position := 0;
      Jpeg.LoadFromStream(Stream);
      Img2.Picture.Assign(Jpeg);
    finally
      Stream.Free();
    end;
  finally
    Jpeg.Free();
  end;
end;
Delphi 7 ortamında database'e kaydetmek için aşağıdaki gibi bir kod kullanmak mümkün olabilir.

Kod: Tümünü seç

uses
  Jpeg;

procedure TForm1.Button1Click(Sender: TObject);
var
  Jpeg: TJpegImage;
  Stream: TStream;
begin
  Jpeg := TJpegImage.Create();
  try
    Jpeg.Assign(Image1.Picture.Graphic);
    Jpeg.CompressionQuality := 95;
    Stream := QRY_1.CreateBlobStream(QRY_1.FieldByName('RESIM6'), bmWrite);
    try
      Jpeg.SaveToStream(Stream);
    finally
      Stream.Free();
    end;
  finally
    Jpeg.Free();
  end;
end;
erdogan_ozkaya
Üye
Mesajlar: 839
Kayıt: 03 Eki 2007 02:00

Re: resim kayıt sorun

Mesaj gönderen erdogan_ozkaya »

Hocam, bilginiz için gerçekten çok teşekkür ederim delphi7 kalmamın sebebi, bir kaç componenet var ve geçiş yapamıyorum :( iki taraftada kayıt yapıp gösteriyorum.

çok teşekkür ederim.
ertank
Kıdemli Üye
Mesajlar: 1716
Kayıt: 12 Eyl 2015 12:45

Re: resim kayıt sorun

Mesaj gönderen ertank »

Delphi 7 içindeki hangi bileşenler sizi XE8'e geçmekten alıkoyuyor?
erdogan_ozkaya
Üye
Mesajlar: 839
Kayıt: 03 Eki 2007 02:00

Re: resim kayıt sorun

Mesaj gönderen erdogan_ozkaya »

org chart, raize components, faster tcp, vlc skin, google map, birde en önemlisi voip die bir bileşenim var program üzerinden telefon görüşmesi yapılıyor bunları geçirmemim bir yolu varmı ?

Teşekkür Ederim.
ertank
Kıdemli Üye
Mesajlar: 1716
Kayıt: 12 Eyl 2015 12:45

Re: resim kayıt sorun

Mesaj gönderen ertank »

Aşağıdaki linkleri bir inceleyin.

-Org chart:
https://www.componentsource.com/product ... tibilities
https://www.steema.com/product/vcl

-Raize Components:
http://www.raize.com/devtools/rzcomps/R ... ations.txt

- Faster TCP: Bu bileşen içinden ne kullandığınızı bilemiyorum. Daha detaylı bilgi verebilirseniz daha ayrıntılı bilgi ermek mümkün olabilir.

- VCL Skin: Delphi XE8 içinde native olarak skin desteği gelmektedir.
- Google Map:
Bu isimli bir bileşen bilmiyorum ancak Google Maps Delphi XE8 ile kullanılabilir.

- VOIP:
http://voipsipsdk.com/products/voip-sip ... i/features
erdogan_ozkaya
Üye
Mesajlar: 839
Kayıt: 03 Eki 2007 02:00

Re: resim kayıt sorun

Mesaj gönderen erdogan_ozkaya »

çok teşekkür ederim, ama voip lisanslı bir bileşen ve xe8 için yok :( ama zaten yeni birşey yapmaya çalışınca xe8 kullanıyorum :) eski bir proje olduğu için delphi7 devam :)
ertank
Kıdemli Üye
Mesajlar: 1716
Kayıt: 12 Eyl 2015 12:45

Re: resim kayıt sorun

Mesaj gönderen ertank »

Aşağıdaki linki incelemenizi tavsiye ederim. Ücretsizdir.
http://tpapro.sourceforge.net/
Cevapla