导航:
论坛 -> 移动应用开发
斑竹:flyers,iamdream
作者:
sxfgf (FC_FGF)
★☆☆☆☆
-
普通会员
2021/12/23 0:56:39
标题:
请教一下,如何优化存储读取图片的速度
浏览:2000
加入我的收藏
楼主:
安卓下, 1、手机拍照或者调用相册里的照片后,如何将图片的变小,方便加快用流存储到数据库的速度? 2、Imagecontrol、ImageViewer里没有stretch属性,怎么才能填充满呢? FMX与VCL差距还是挺大的,请赐教具体的方法,谢谢
----------------------------------------------
偶尔做做代码应付一下工作,却发现Delphi已成必配
作者:
2021/12/23 6:40:01
1楼:
1) you can use the class from Android API directly on FMX project ---> android.graphics.Bitmap.CompressFormat unit FMX.Graphics.Android; ********** function TBitmapCodecAndroid.SaveToStream(const AStream: TStream; const Bitmap: TBitmapSurface; const Extension: string; const SaveParams: PBitmapCodecSaveParams): Boolean; ********** but if the image already compressed nothing will be done!!! 2) you can "zip" it, but... normally images on Android use compress-format by default (JPeg, Gif, PNG, Webp, etc...) - zip can help on size just!!! for image "stretch/original/etc.. mode" you need use a TImage as target.
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
2021/12/23 6:41:00
2楼:
procedure TForm1.Button3Click(Sender: TObject); var AStream : TStream; NativeBitmap : JBitmap; SaveFormat : JBitmap_CompressFormat; SaveQuality : Integer; OutByteStream: JByteArrayOutputStream; ContentBytes : TJavaArray<Byte>; resulted : boolean; begin NativeBitmap := TJBitmap.JavaClass.createBitmap(Image1.Bitmap.Width, Image1.Bitmap.Height, TJBitmap_Config.JavaClass.ARGB_8888); try if not(SurfaceToJBitmap(TBitmapSurface(Image1.Bitmap), NativeBitmap)) then exit; // SaveFormat := TJBitmap_CompressFormat.JavaClass.PNG; // OutByteStream := TJByteArrayOutputStream.JavaClass.init(0); // SaveQuality := 75 { default quality }; // resulted := NativeBitmap.compress(SaveFormat, SaveQuality, OutByteStream); finally NativeBitmap.recycle; end; // AStream := TStream.Create; try if resulted and (OutByteStream.size > 0) then begin ContentBytes := OutByteStream.toByteArray; try AStream.WriteBuffer(ContentBytes.Data^, OutByteStream.size); finally FreeAndNil(ContentBytes); end; end; finally /// ??????? //// AStream.Free; end; // // resulted := resulted and (OutByteStream.size > 0); end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
2021/12/23 6:41:55
3楼:
uses Androidapi.JNI.GraphicsContentViewText, FMX.Graphics, FMX.Surfaces, FMX.Helpers.Android; function BitmapToJBitmap(const ABitmap: TBitmap): JBitmap; var LSurface: TBitmapSurface; begin Result := TJBitmap.JavaClass.createBitmap(ABitmap.Width, ABitmap.Height, TJBitmap_Config.JavaClass.ARGB_8888); LSurface := TBitmapSurface.Create; try LSurface.Assign(ABitmap); SurfaceToJBitmap(LSurface, Result); finally LSurface.Free; end; end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
2021/12/23 9:09:16
4楼:
emailx45能力真强,各种代码都能来得
----------------------------------------------
-
作者:
2021/12/23 10:41:35
5楼:
楼主问题没描述清楚。 是把图片文件变小?那就是压缩图片为 JPG 等格式; 是把图片尺寸变小? 如果图片尺寸过大 -- 现在手机拍照的像素太多,导致图片尺寸太大,如果你的应用需求不需要那么大的图片,可以对图片尺寸(分辨率)做一次缩放,然后对缩小尺寸后的图片,再做 JPG 压缩。这样可以得到比较小的数据量。
----------------------------------------------
-
作者:
sxfgf (FC_FGF)
★☆☆☆☆
-
普通会员
2021/12/23 12:23:25
6楼:
pcplayer 您好 主要是实现手机拍照后像素太大,照片体积太大,网路传输及读取数据库时速度太慢,而几乎不需要太好质量的图片,以提高显示及读取速度 问题就是不知道如何把图片尺寸(分辨率)降低,再转成JPG格式
----------------------------------------------
偶尔做做代码应付一下工作,却发现Delphi已成必配
作者:
2021/12/23 16:10:04
7楼:
你的问题不是语言的问题,是库的问题。比如,在 VCL 底下,可能是用什么函数,在 FMX 底下,又是用另外的函数。你现在说的是手机,那么我假设你是在 FMX 底下。 我需要打开 Delphi 自己写个代码试试。
----------------------------------------------
-
作者:
2021/12/23 16:53:00
8楼:
上网查了一下资料,测试通过的代码如下: uses FMX.Surfaces; procedure TForm1.Button1Click(Sender: TObject); var Bmp: TBitmap; Src, Trg: TRectF; NewWidth, NewHeight: Integer; AStream: TFileStream; Surf: TBitmapSurface; begin if OpenDialog1.Execute then begin Image1.Bitmap.LoadFromFile(OpenDialog1.FileName); Src := RectF(0, 0, Image1.Bitmap.Width, Image1.Bitmap.Height); //这里缩小一半 NewWidth := Trunc(Image1.Bitmap.Width / 2); NewHeight := Trunc(Image1.Bitmap.Height / 2); Trg := RectF(0, 0, NewWidth, NewHeight); Bmp := TBitmap.Create; try Bmp.Width := NewWidth; Bmp.Height := NewHeight; Bmp.Canvas.BeginScene; try Bmp.Canvas.DrawBitmap(Image1.Bitmap, Src, Trg, 1) finally Bmp.Canvas.EndScene; end; Image2.Bitmap.Assign(Bmp); // 保存的文件名带 jpg ,自动压缩为 JPG Bmp.SaveToFile('D:\testAAA.jpg'); //保存到 Stream 看看 Surf := TBitmapSurface.Create; AStream := TFileStream.Create('D:\testAAABB.jpg', fmCreate); try Surf.Assign(Bmp); //这个方法,通过字符串 .jpg 指定它输出时编码为 jpg,测试通过。 TBitmapCodecManager.SaveToStream(AStream, Surf, '.jpg', nil); finally AStream.Free; Surf.Free; end; finally Bmp.Free; end; end; end
----------------------------------------------
-
作者:
2021/12/24 17:40:18
9楼:
1,指针读写; 2,多线程分段读写。 要快么?
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
作者:
sxfgf (FC_FGF)
★☆☆☆☆
-
普通会员
2021/12/25 1:11:16
10楼:
各位大哥: 是做的安卓APP,调用的摄像头或者相册里的照片作为商品的图片,现在是每次存入商品图片时非常的耗时,读取显示存入数据库的时候也特别费时间, 为了提高读取显示,存入速度,牺牲一些照片的清晰度都没关系。只要能看清除是啥东西就行。 目前根据 pcplayer 提供的代码这样做的: var Stream:TMemoryStream; var Bmp: TBitmap; var Src, Trg: TRectF; var NewWidth, NewHeight: Integer; //var AStream: TFileStream; var Surf: TBitmapSurface; begin //图片 if CheckBox1.IsChecked=True then begin Src := RectF(0, 0, ImageControl1.Bitmap.Width, ImageControl1.Bitmap.Height); NewWidth := Trunc(ImageControl1.Bitmap.Width / 20); NewHeight := Trunc(ImageControl1.Bitmap.Height / 20); Trg := RectF(0, 0, NewWidth, NewHeight); Bmp := TBitmap.Create; try Bmp.Width := NewWidth; Bmp.Height := NewHeight; Bmp.Canvas.BeginScene; try Bmp.Canvas.DrawBitmap(ImageControl1.Bitmap, Src, Trg, 1); finally Bmp.Canvas.EndScene; end; Surf := TBitmapSurface.Create; Stream := TMemoryStream.Create; // 创建内存流 try Surf.Assign(Bmp); TBitmapCodecManager.SaveToStream(Stream, Surf, '.jpg', nil); finally Stream.Free; Surf.Free; end; finally Bmp.Free; end; sql:='insert into Fc_GoodsImage (PTypeID,Picture) values ( '; sql:=sql+':ID,:pic)'; ClientModule1.ClientDataSet1.Close; ClientModule1.ClientDataSet1.CommandText:=sql; ClientModule1.ClientDataSet1.ParamByName('id').Value:=cBaseNo; ClientModule1.ClientDataSet1.ParamByName('pic').LoadFromStream(Stream,ftBlob); ClientModule1.ClientDataSet1.Execute; end; 但是,效果不是很明显,速度还是挺慢的 请大神赐教
----------------------------------------------
偶尔做做代码应付一下工作,却发现Delphi已成必配
作者:
2021/12/26 9:41:37
11楼:
给你换个思路吧,你是调用摄像头,那么你直接程序自开摄像头拍照的时候直接拍成成小图存储就好了,非要调用摄像头图片吗?fmx下不是有摄像头例子吗?简单看看换个思路就可以解决你的需求,解决需求可以多种方法,达到目的就可以了~,图片压缩不管你在什么平台下都耗时的~
----------------------------------------------
-
作者:
2021/12/26 9:44:40
12楼:
还有一点,感觉有点不合理的地方~图片资源一般不存入数据库的吧~
----------------------------------------------
-
作者:
sxfgf (FC_FGF)
★☆☆☆☆
-
普通会员
2021/12/26 23:51:06
13楼:
xxz1314: 是的如果不把数据库存入数据库里,那还得搞一个图片服务器 存入数据库把的确影响速度,但是相对独立经济一些 不过,直接拍成小图这个思路挺好
----------------------------------------------
偶尔做做代码应付一下工作,却发现Delphi已成必配
作者:
2021/12/27 11:45:59
14楼:
楼上,你的代码: 1. 你前面 Stream.Free 了,后面 ClientModule1.ClientDataSet1.ParamByName('pic').LoadFromStream(Stream,ftBlob); 2. 你的代码,你可以逐行加上 GetTickCount 获取当前时间,后面的时间减前面的时间,看看你的时间消耗,究竟在哪里。比如,是在缩放图片那里,还是在 ClientModule1.ClientDataSet1.Execute; 这里。 因为不知道你的 ClientDataSet 和服务器之间的带宽,不好判断你的时间花在哪里。
----------------------------------------------
-