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.