-
新手请教:关于绘制图片的效率
2012-07-14 14:27:14在表格上绘制图片 同时用了两种方法 e.Graphics.FillEllipse e.Graphics.DrawString 添加一个imagelist1 e.Graphics.DrawImage 请问:这样影响效率吗?还是只保留一种? -
关于将网络上的图片下载保存到本地的效率对比
2011-06-10 11:28:20Android里面将图片保存到本地,到网络上搜索了一下,方法都差不多,大同小异,把输入流转换成输出流的过程而已。最近工作闲,特把其中的两个方法对比一下,看他们的效率如何(找javaSE里面测试的): [b]第一种...Android里面将图片保存到本地,到网络上搜索了一下,方法都差不多,大同小异,把输入流转换成输出流的过程而已。最近工作闲,特把其中的两个方法对比一下,看他们的效率如何(找javaSE里面测试的):
[b]第一种方法:[/b]public static void main(String[] args) {
String url = "http://pic.yesky.com/imagelist/09/01/11277904_7147.jpg";
Long time1 = System.currentTimeMillis();
Long time2 = 0L;
try {
FileOutputStream fos = new FileOutputStream( "c:\\tmp.jpg ");
InputStream is = new URL(url).openStream();
time2 = System.currentTimeMillis();
int data = is.read();
while(data!=-1){
fos.write(data);
data=is.read();
}
is.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
Long time3 = System.currentTimeMillis();
System.out.println("网络读取流的时间:" + (time2 - time1) + " 把输入流保存成文件的时间:"+ (time3 - time2));
}
[b]第二种方法:中间用buffer做缓存[/b]public static void main(String[] args){
String url = "http://pic.yesky.com/imagelist/09/01/11277904_7147.jpg";
Long time1 = System.currentTimeMillis();
Long time2 = 0L;
try {
int bytesum=0;
int byteread=0;
FileOutputStream fos = new FileOutputStream( "c:\\tmp2.jpg ");
InputStream is = new URL(url).openStream();
time2 = System.currentTimeMillis();
byte[] buffer =new byte[4096];
while ((byteread=is.read(buffer))!=-1)
{
bytesum+=byteread;
// System.out.println(bytesum);
fos.write(buffer,0,byteread);
}
is.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
Long time3 = System.currentTimeMillis();
System.out.println("网络读取流的时间:" + (time2 - time1) + " 把输入流保存成文件的时间:"+ (time3 - time2));
}
每个方法测试了三次,结果如下:
第一种方法:
网络读取流的时间:453 把输入流保存成文件的时间:766
网络读取流的时间:344 把输入流保存成文件的时间:344
网络读取流的时间:297 把输入流保存成文件的时间:281
第二种方法:
网络读取流的时间:312 把输入流保存成文件的时间:282
网络读取流的时间:3484 把输入流保存成文件的时间:906
网络读取流的时间:828 把输入流保存成文件的时间:1250
第一种方法,发现效率高过第二种方法,而且第一种方法写法简洁的多。[b][color=red]建议用第一种方法[/color][/b]。
其实在android里面,不建议直接把网络图片原样写人sd里面,毕竟手机的sd空间是有限的。最常用的方法是把网络图片压缩成jpg格式保存:byte[] data = readInputStream(new URL(url).openStream());
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
data.length);
bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(
file));
readInputStream()方法的代码:(把输入流转换成比特流)public static byte[] readInputStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int len = 0;
while( (len = inStream.read(buffer)) != -1 ){
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
return outSteam.toByteArray();
} -
使用Pandas的迭代以及其他关于效率的一点记录
2019-12-27 15:22:14使用Pandas的迭代以及其他关于效率的一点记录欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个...使用Pandas的迭代以及其他关于效率的一点记录
1.将Series转成DataFrame进行iterrows迭代(初学Pandas,开始不知道Series可以迭代)计算强度 耗时: 464.36 秒
2.使用 Series.items(等同itertems()),迭代计算
计算强度 耗时: 50.41 秒
从这个结果看时间可能是消耗在Series转成DataFrame。
3.使用 Series.iter(),进行迭代计算,这个是只对序列的值进行迭代,我的计算刚好用不上index,测试了下很吃惊。
计算强度 耗时: 18.09 秒
iter,两边有下划线,上边的不知道为何显示不出来。看来只对values迭代,相对 index和values要快不少。
以上这些时间的记录还包含了其他的代码运行时间,如果刨除,将显示效率提高的更高。
4.对DataFrame使用drop删除操作
在iterrows迭代中进行对DataFrame的删除操作,如果符合条件,将当前行删除 drop(index)转换15to30 耗时: 351.42 秒
在迭代中,将符合条件的index加入一个数列 list(index),迭代完成之后,进行删除操作,drop(list(index))
转换15to30 耗时: 7.11 秒
以上的这些巨大的提升使我震惊VQChwi4XYBzonNUSDJl0om7WlvE+WCTurz3njfeXmfM=\n,看来正确使用Pandas至关重要。02JD611N0ldoD1k0a61w1c有效期20210308
-
关于图片轮播代码的选择?考虑效率,复杂度。
2015-12-30 17:02:02关于图片轮播代码的选择,度娘了一下 ,貌似有很多种的啊。 1.javascript实现 1. 动态移动法,就是把移动前的li append到后边来,以此达到轮播的效果。 2. 视觉移动法,就是复制容器的元素,然后在视觉临界点的... -
delphi XE关于Android四大组件之ContentProvider:案例delphi XE加载Android手机图片的效率
2020-04-20 19:24:51一、常用的单元引用 uses FMX.Helpers.Android; //:Android线程与线程池、Android处理基本的绘制 TUIThreadCaller = class //:线程调用类(匿名方法、异步调用与回调、强制出队) procedure CallInUIThread...目录
delphi调用Android APIs的ContentProvider组件读取手机媒体库图片-开发App(一)运用Android四大组件
1.1、常用的单元引用uses FMX.Helpers.Android;
1.2、常用的单元引用uses Androidapi.JNI.Provider;
1.3、常用的单元引用uses Androidapi.JNI.Media;
delphi调用Android APIs的ContentProvider组件读取手机媒体库图片-开发App(一)运用Android四大组件
第一部分 原理篇
1.1、常用的单元引用uses FMX.Helpers.Android;
//:Android线程与线程池、Android处理其系统内基本的表面绘制、Android数组转化
const
/// <summary>Minimum base action number for using in Android Intent</summary>
UserRequestCodeBase = 10; //:请求Android的Intent,至少被调用的应用内置要有10个Action操作
function IsGingerbreadDevice: Boolean; //:是否为姜黄饼干样的设备:指老掉牙的设备:TOSVersion.Major = 2;//设置为主题皮肤:0-返回样式描述不成功-代表该窗体中没有样式本TStyleBook或有但未设置:用原生方法将Fmx的样式本设置为主题皮肤:
function GetNativeTheme: Integer; overload;
function GetNativeTheme(const AControl: TControl): Integer; overload; //:获取原生主题皮肤{ 几个处理基本表面绘制的函数:Surface convertions }
function JBitmapToSurface(const SrcBitmap: JBitmap; const DestSurface: TBitmapSurface): Boolean;
function SurfaceToJBitmap(const SrcSurface: TBitmapSurface; const DestBitmap: JBitmap): Boolean;
function NativeViewToSurface(const ANativeView: JView; const ASurface: TBitmapSurface): Boolean;{ 产生传入Java数组的转化函数:Java array conversion }
function CreateJavaStringArray(const ASource: array of const): TJavaObjectArray<JString>;
{ 用UI线程(即主线程)工作的内容:Work with UI Thread }
TUIThreadCaller = class //:线程调用类(匿名方法、异步调用与回调、强制出队)
TFinishedRunnableCollector = class //:处理已完成的线程(或任务)的列表容器类var
ActiveJavaRunnables: TThreadList<TRunnable>; //:活动的任务的线程队列列表容器变量:uses System.Generics.Collections;
在UI线程中调用“回调事件或回调匿名方法”子线程的几个过程:线程入队-先进先出(非栈模式:进栈压入-后进先出-出栈弹出):procedure CallInUIThread(AMethod: TMethodCallback); overload;
procedure CallInUIThread(AMethod: TCallBack); overload; //: UI线程直接执行被调用的子线程,但暂未释放,等待操作系统自动释放或等待引用窗体Activity被代码disposeof后释放,或UI线程(即主线程)被操作者关闭后自动释放:异步非阻塞模式的队列线程池模式。
procedure CallInUIThreadAndWaitFinishing(AMethod: TMethodCallback); overload;
procedure CallInUIThreadAndWaitFinishing(AMethod: TCallBack); overload; //: UI线程等待被调用的线程执行完毕,线程出队出栈弹出:异步非阻塞的队列线程池模式:uses System.SyncObjs; //:其中调用了TEvent事件总线监控:Event.SetEvent; Event.WaitFor:子线程执行完毕立即释放initialization
ActiveJavaRunnables := TThreadList<TRunnable>.Create; //:初始化:活动的任务的线程列表变量(初始化线程队列容器)finalization
ActiveJavaRunnables.DisposeOf; //:释放:活动的任务的线程列表变量(释放线程队列容器,并释放其中的未被释放的子线程-按队列先进先出)
end.1.2、常用的单元引用uses Androidapi.JNI.Provider;
//:Android的五大存储之四的内容提供者(ContentProvider)及内容接收器(ContentResolver)的处理单元
1.2.1、应用1:Android安卓系统缩略图内容提供者及内容接收器
JImages_ThumbnailsClass = interface(JObjectClass)
{class} function getThumbnail(cr: JContentResolver; origId: Int64; kind: Integer; options: JBitmapFactory_Options): JBitmap; cdecl; overload;
{class} function getThumbnail(cr: JContentResolver; origId: Int64; groupId: Int64; kind: Integer; options: JBitmapFactory_Options): JBitmap; cdecl; overload;
{class} function query(cr: JContentResolver; uri: Jnet_Uri; projection: TJavaObjectArray<JString>): JCursor; cdecl;
{class} function queryMiniThumbnail(cr: JContentResolver; origId: Int64; kind: Integer; projection: TJavaObjectArray<JString>): JCursor; cdecl;
{class} function queryMiniThumbnails(cr: JContentResolver; uri: Jnet_Uri; kind: Integer; projection: TJavaObjectArray<JString>): JCursor; cdecl;
[JavaSignature('android/provider/MediaStore$Images$Thumbnails')] //:内容提供者签名共享的URI路径内容
JImages_Thumbnails = interface(JObject)
['{29CB9363-CD45-4C6E-86EF-FD421A2C7A11}']
end;
TJImages_Thumbnails = class(TJavaGenericImport<JImages_ThumbnailsClass, JImages_Thumbnails>) end;其中:thumbnail_cache路径是用Sqlite本地数据库缓存的,所以本质上是调用存取数据库的操作:
该数据库的表结构如下:
CREATE TABLE kv(k INTEGER PRIMARY KEY, v BLOB);
因而:介绍完原理之后,最后面就会作为一个案例分析:FMX调用该数据库进行缩略图列表和用Android原生方法列表缩略图的效率比较。
1.3、常用的单元引用uses Androidapi.JNI.Media;
//:Android媒体及其处理单元
1.3.1、应用1:缩略图工具类:
JThumbnailUtilsClass = interface(JObjectClass)
['{5D772E54-5912-4CF0-A97D-0A4B171E7EF7}']
{class} function _GetOPTIONS_RECYCLE_INPUT: Integer; cdecl; //:获取选项-回收再利用选项
{class} function init: JThumbnailUtils; cdecl; //:初始化实例化本工具类
{class} function createVideoThumbnail(filePath: JString; kind: Integer): JBitmap; cdecl; //:产生视频缩略图
{class} function extractThumbnail(source: JBitmap; width: Integer; height: Integer): JBitmap; cdecl; overload;
{class} function extractThumbnail(source: JBitmap; width: Integer; height: Integer; options: Integer): JBitmap; cdecl; overload; //:提取缩略图
{class} property OPTIONS_RECYCLE_INPUT: Integer read _GetOPTIONS_RECYCLE_INPUT;//:回收再利用选项属性
end;[JavaSignature('android/media/ThumbnailUtils')]
JThumbnailUtils = interface(JObject)
['{EF230179-DF54-4876-A9BC-5D982DF95E21}']
end;
TJThumbnailUtils = class(TJavaGenericImport<JThumbnailUtilsClass, JThumbnailUtils>) end;第二部分 案例篇
2.1、直接上代码(内附详细说明):
unit MasterDetail; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, System.Rtti, System.Bindings.Outputs, System.Actions, {$IFDEF Android} FMX.Helpers.Android, Androidapi.IOUtils, Androidapi.Helpers, Androidapi.JNI.Provider, Androidapi.JNIBridge, Androidapi.JNI.JavaTypes, Androidapi.JNI.Net, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Media, {$ENDIF Android} Data.Bind.GenData, Data.Bind.Components, Data.Bind.ObjectScope, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.ListView.Types, Fmx.Bind.GenData, Fmx.Bind.Editors, Data.Bind.EngExt, Fmx.Bind.DBEngExt, FMX.Objects, FMX.StdCtrls, FMX.ListView, FMX.ListView.Appearances, FMX.Layouts, FMX.MultiView,FMX.Memo, Fmx.Bind.Navigator, FMX.ActnList, FMX.ListView.Adapters.Base, FMX.ScrollBox, FMX.Controls.Presentation; type TMasterDetailForm = class(TForm) MultiView1: TMultiView; Layout1: TLayout; ListView1: TListView; MasterToolbar: TToolBar; MasterLabel: TLabel; DetailToolbar: TToolBar; DetailLabel: TLabel; MasterButton: TSpeedButton; imgContact: TImage; lblName: TLabel; lblTitle: TLabel; ActionList1: TActionList; PrototypeBindSource1: TPrototypeBindSource; BindingsList1: TBindingsList; LinkPropertyToFieldBitmap: TLinkPropertyToField; LinkPropertyToFieldText: TLinkPropertyToField; LinkPropertyToFieldText2: TLinkPropertyToField; LinkControlToField1: TLinkControlToField; LinkListControlToField1: TLinkListControlToField; LiveBindingsBindNavigateNext1: TFMXBindNavigateNext; LiveBindingsBindNavigatePrior1: TFMXBindNavigatePrior; Layout2: TLayout; Layout3: TLayout; Memo1: TMemo; btnUp: TSpeedButton; btnDown: TSpeedButton; MetropolisUIBlue_touch: TStyleBook;//:加个你的FMX样式本控件 procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure MultiView1StartShowing(Sender: TObject); procedure ListView1UpdateObjects(const Sender: TObject; const AItem: TListViewItem); procedure ListView1UpdatingObjects(const Sender: TObject; const AItem: TListViewItem; var AHandled: Boolean); procedure ListView1ScrollViewChange(Sender: TObject); procedure ListView1ItemClick(const Sender: TObject; const AItem: TListViewItem); procedure MasterLabelClick(Sender: TObject); private FPicPath:string; FImgsStringList:TStringList; FDefaultRecordCound_PrototypeBindSource:Integer; FUpdatingItemView:Boolean;//:ItemView是否正在更新或更新已完毕 procedure FetchAndroidSysdada(URI_ContentProvider:Jnet_Uri); { Private declarations } public { Public declarations } end; var MasterDetailForm: TMasterDetailForm; //本案注释部分和lblTitle即Memo1的赋值主要用于调试: implementation {$R *.fmx} uses myFuc_UnifiedPlatForm, myFuc_Client; //:这是我自己用的库单元,主要用于本例需要使用的权限和下面的路径生成(路径本例可不用) procedure TMasterDetailForm.FormDestroy(Sender: TObject); begin if Assigned(FImgsStringList) then FImgsStringList.Free; end; procedure TMasterDetailForm.FormCreate(Sender: TObject); begin try AndoidRequestPermissions(['管理文档','读取文件','写入文件']);//:合称"存储权限" //:你需要实现Android运行时的动态权限申请和用户确认 finally try SubPathOfAppPublished; //:路径生成(路径本例可不用) finally FPicPath:=GetSubPathOfAppPublished; //:路径获取(路径本例可不用) end; {$IFDEF Android} //ShowMessage(GetNativeTheme(MultiView1).ToString);//:0-返回样式描述不成功-代表该窗体中没有样式本TStyleBook或有但未设置 //ShowMessage(GetSharedPicturesDir+'/'+'thumbnail_cache'); {$ENDIF Android} end; end; procedure TMasterDetailForm.ListView1ItemClick(const Sender: TObject; const AItem: TListViewItem); begin MultiView1.HideMaster; end; procedure TMasterDetailForm.ListView1ScrollViewChange(Sender: TObject); var LItem: TListViewItem; LTableStruct_SplitStrArray:TArray<string>; //:缩略图表结构字段数值字符串分割数组:长度为:6:下面共6个字段 LFilePath_NameArray:TArray<string>; //:缩略图文件存取路径字符串分割数组 L_id,L_data,Limage_id,Lkind,Lwidth,Lheight:string; //:缩略图表结构字段数值变量:共6个字段 begin //PrototypeBindSource1 //if FDefaultRecordCound_PrototypeBindSource < FImgsStringList.Count then if ListView1.ItemCount < FImgsStringList.Count then begin LItem:=ListView1.Items.Add; INC(FDefaultRecordCound_PrototypeBindSource); LTableStruct_SplitStrArray:=FImgsStringList[LItem.Index].Split([',']); L_id:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-6];//:即LTableStruct_SplitStrArray[0] L_data:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-5];//:即LTableStruct_SplitStrArray[1] Limage_id:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-4];//:即LTableStruct_SplitStrArray[2] Lkind:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-3];//:即LTableStruct_SplitStrArray[3] Lwidth:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-2];//:即LTableStruct_SplitStrArray[4] Lheight:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-1];//:即LTableStruct_SplitStrArray[5] LFilePath_NameArray:=L_data.Trim.Split(['/']); LItem.Text:=LFilePath_NameArray[Length(LFilePath_NameArray)-1]; //lblTitle.Text:=' 索引: '+LItem.Index.ToString +' ,存取路径: '+L_data.Trim //+' ,当前加载图片数Items.Count: '+ListView1.Items.Count.ToString.Trim; //+' ,ItemCount: '+ListView1.ItemCount.ToString.Trim //:200默认PrototypeBindSource1每页记录数 end; //LTableStruct_SplitStr:= //L_id.ToString+','+L_data.Trim+','+Limage_id.ToString+',' //+Lkind.ToString+','+Lwidth.ToString+','+Lheight.ToString; end; procedure TMasterDetailForm.ListView1UpdateObjects( const Sender: TObject; const AItem: TListViewItem); var LListItemImage:TListItemImage; LTableStruct_SplitStrArray:TArray<string>; //:缩略图表结构字段数值字符串分割数组:长度为:6:下面共6个字段 LFilePath_NameArray:TArray<string>; //:缩略图文件存取路径字符串分割数组 L_id,L_data,Limage_id,Lkind,Lwidth,Lheight:string; //:缩略图表结构字段数值变量:共6个字段 begin if (AItem<>nil) and (AItem.View.DrawableByName('I')<>nil) then begin //lblTitle.Text:='找到了:'+AItem.View.DrawableByName('I').Name; LTableStruct_SplitStrArray:=FImgsStringList[AItem.Index].Split([',']); L_id:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-6];//:即LTableStruct_SplitStrArray[0] L_data:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-5];//:即LTableStruct_SplitStrArray[1] Limage_id:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-4];//:即LTableStruct_SplitStrArray[2] Lkind:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-3];//:即LTableStruct_SplitStrArray[3] Lwidth:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-2];//:即LTableStruct_SplitStrArray[4] Lheight:= LTableStruct_SplitStrArray[Length(LTableStruct_SplitStrArray)-1];//:即LTableStruct_SplitStrArray[5] LFilePath_NameArray:=L_data.Trim.Split(['/']); AItem.Text:=LFilePath_NameArray[Length(LFilePath_NameArray)-1]; AItem.BeginUpdate; LListItemImage:=(AItem.View.DrawableByName('I') as TListItemImage); LListItemImage .Bitmap.LoadThumbnailFromFile( L_data,//FImgsStringList[AItem.Index].Trim, LListItemImage.Width*(Lwidth.ToInteger/Lheight.ToInteger), LListItemImage.Height*(Lwidth.ToInteger/Lheight.ToInteger), true); //if Lheight.ToInteger>Lwidth.ToInteger then LListItemImage.Bitmap.Rotate(90);//:控制旋转 AItem.EndUpdate; end; lblTitle.Text:='索引:'+AItem.Index.ToString +',存取路径: '+L_data.Trim +' ,当前加载图片数Items.Count: '+ListView1.Items.Count.ToString.Trim; //+' ,ItemCount: '+ListView1.ItemCount.ToString.Trim //:200默认PrototypeBindSource1每页记录数 //LTableStruct_SplitStr:= //L_id.ToString+','+L_data.Trim+','+Limage_id.ToString+',' //+Lkind.ToString+','+Lwidth.ToString+','+Lheight.ToString; FUpdatingItemView:= false;//:ItemView是否正在更新或更新已完毕 end; procedure TMasterDetailForm.ListView1UpdatingObjects(const Sender: TObject; const AItem: TListViewItem; var AHandled: Boolean); begin FUpdatingItemView:= true;//:ItemView是否正在更新或更新已完毕 end; procedure TMasterDetailForm.MasterLabelClick(Sender: TObject); var LCurrentTotalItemsCount: Integer; begin //if FUpdatingItemView= true then exit;//:ItemView是否正在更新或更新已完毕 try LCurrentTotalItemsCount:=ListView1.Items.Count; //if ListView1.ScrollViewPos then finally if MasterLabel.Text.Trim='到开头' then begin ListView1.ScrollTo(0); MasterLabel.Text:='到当前已加载图片的末尾'; end else begin //:设置ListView的当前索引:ListView1.ItemIndex:=ListView1.ItemCount; //ListView1.Items.AppearanceItem[ListView1.ItemCount]; try ListView1.ScrollTo(LCurrentTotalItemsCount-1); finally MasterLabel.Text:='到开头'; end; end; end; end; procedure TMasterDetailForm.MultiView1StartShowing(Sender: TObject); var URI_ContentProvider:Jnet_Uri; begin //:调用ContentResolver提取ContentProvider的数据//uses Androidapi.JNI.Provider CallInUIThreadAndWaitFinishing( procedure begin URI_ContentProvider:=StrToJURI('content://media/external/images/thumbnails');//:uses Androidapi.Helpers; FetchAndroidSysdada(URI_ContentProvider); //:如果你不知道正确的URI,请FetchAndroidSysdada(nil); end); //:这些都是错误的URI: //content://android.providers.media/thumbnail_cache/thumbnail.db/kv //content://android.provider.MediaStore$Images$Thumbnails //MediaStore.Audio.Images.INTERNAL_CONTENT_URI end; procedure TMasterDetailForm.FetchAndroidSysdada(URI_ContentProvider:Jnet_Uri); var LContext: JContext; LJContentResolver: JContentResolver; Lprojection: TJavaObjectArray<JString>; LJavaBasicArray:TJavaBasicArray; LJCursor: JCursor; LRecCount, LRecIndex: Integer; LColumnCounts, LColumnFieldType: Integer; LColumnName: string; LImgBlobTBytes:TJavaArray<Byte>; LImageIndex:Integer; LImagePathInStringList: string; LIFImageDuplicates:Boolean; LTableStruct_SplitStr: string; //:用于存取下属表结构字段数值并用,分割后,写入全局列表FImgsStringList //以下几个变量一一对应表中的各字段(去变量前置L字符即是): L_id: Integer; L_data: string; Limage_id: Integer; Lkind: Integer; Lwidth: Integer; Lheight: Integer; begin //参考:FMX.AddressBook.Android: //procedure TAndroidAddressBook.FetchContacts(var AContacts: TAddressBookContacts; const AFilter: string = ''); LJavaBasicArray:=TJavaBasicArray.Create; //Lprojection:= CreateJavaStringArray(['kv.k','kv.v']);//TJavaObjectArray<JString>.Wrap(LJavaBasicArray); Lprojection:= CreateJavaStringArray(['*']);//TJavaObjectArray<JString>.Wrap(LJavaBasicArray); //:'*': select * 字段列表 //LJContentResolver:=TJContentResolver.JavaClass.init(LContext); //: 抽象内容 //URI_ContentProvider:=TJImages_Thumbnails.JavaClass.getContentUri(StringToJString(GetSharedPicturesDir+'/thumbnail_cache')); //: 抽象内容 if URI_ContentProvider=nil then URI_ContentProvider:=TJImages_Thumbnails.JavaClass.EXTERNAL_CONTENT_URI; //:URI不能为nil:不能使用抽象内容的提供者方法:如果访问外部内容提供者的内容(用户的数据)要有权限 //Memo1.Lines.Clear; //Memo1.Lines.Add(JStringToString(TJImages_Thumbnails.JavaClass.INTERNAL_CONTENT_URI.toString)); //:INTERNAL_CONTENT_URI:内部数据-系统只对外提供表结构,记录数始终=0 //URI数值:content://media/internal/images/thumbnails //Memo1.Lines.Add(JStringToString(TJImages_Thumbnails.JavaClass.EXTERNAL_CONTENT_URI.toString)); //:EXTERNAL_CONTENT_URI:用户的数据(外部内容提供者的内容):需要READ_EXTERNAL_STORAGE权限或grantUriPermission(); //URI数值:content://media/external/images/thumbnails //Memo1.Lines.Add(JStringToString(TJImages_Thumbnails.JavaClass.THUMB_DATA));//:返回'thumb_data'没起什么作用 LJCursor:=TAndroidHelper.ContentResolver .query( URI_ContentProvider,//TJImages_Thumbnails.JavaClass.INTERNAL_CONTENT_URI,//:查询的表名 Lprojection, //:查询的列数组 StringToJString(string.Empty), //:查询的where条件 nil, //:查询参数数组:where中的占位符提供具体的值 StringToJString('_data desc') //:查询的排序字段的字符串列表','分割:_data根据下面字段列表反推得到 //_data:被分割提取后的文件名:就是时间截13位的其中后3位为毫秒:可用于排序和时间分类,就和手机自带的【图库】一样: //LFilePath_NameArray:=FImgsStringList[LItem.Index].Split(['/']); //LItem.Text:=LFilePath_NameArray[Length(LFilePath_NameArray)-1]; ); {LJCursor:=TJImages_Thumbnails.JavaClass .queryMiniThumbnail( LJContentResolver, 0, 1, Lprojection ); //} //function query(uri: Jnet_Uri; projection: TJavaObjectArray<JString>; selection: JString; selectionArgs: TJavaObjectArray<JString>; sortOrder: JString): JCursor; {对应参数的解释://https://blog.csdn.net/xianKOG/article/details/81702119?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158731319919724846464763%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=158731319919724846464763&biz_id=0&utm_source=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-4 query()方法的参数:相当于本地sqlite缓存数据库下SQL部分 描述: uri from table_name 指定查询某个应用程序下的某个表 projection select column1, column2 指定查询的列名 selection where column=value 指定where约束条件 selectArgs 为where中的占位符提供具体的值 orderBy order by column1, column2 指定查询结果的排序方式} LRecCount:=LJCursor.getCount; //Memo1.Lines.Add('表中记录数:'+LRecCount.ToString); if LRecCount>0 then //:如果表存在且有记录:Sqlite:始终有1条记录,哪怕表记录为空 begin //LJCursor.getColumnCount LJCursor.moveToFirst; //:如果不给这一句:游标的索引越界 LColumnCounts:=0; while LColumnCounts<LJCursor.getColumnCount do begin LColumnName:=JStringToString(LJCursor.getColumnName(LColumnCounts)); LColumnFieldType:= LJCursor.getType(LColumnCounts); //Memo1.Lines.Add('表列名('+LColumnCounts.ToString+'):'+LColumnName+',列字段类型索引:'+LColumnFieldType.ToString); INC(LColumnCounts); end; //:获取的表结构如下://URI_ContentProvider=TJImages_Thumbnails.JavaClass.INTERNAL_CONTENT_URI //表中记录数:0 //表列名(0):_id //表列名(1):_data //表列名(2):image_id //表列名(3):kind //表列名(4):width //表列名(5):height //:获取记录总数及表结构如下://URI_ContentProvider=TJImages_Thumbnails.JavaClass.EXTERNAL_CONTENT_URI //表中记录数:5353 //表列名(0):_id,列字段类型索引:1 (1:整数类型) 字段含义:缩略图表_id号,与Sqlite自增长字段相关 //表列名(1):_data,列字段类型索引:3 (3:字符串类型) 字段含义:缩略图的手机存取路径 //表列名(2):image_id,列字段类型索引:1 字段含义:缩略图编码关联字段,默认=_id //表列名(3):kind,列字段类型索引:1 字段含义:缩略图来源类型:比如图片媒体:1(默认),视频媒体2(未去验证):实际未怎么使用 //表列名(4):width,列字段类型索引:1 字段含义:缩略图的宽度像素 //表列名(5):height,列字段类型索引:1 字段含义:缩略图的高度像素 LJCursor.moveToFirst; LRecIndex:=1; LJCursor.getWantsAllOnMoveCalls; if not Assigned(FImgsStringList) then FImgsStringList:=TStringList.Create; FImgsStringList.Clear; //Memo1.Lines.Add('各记录数值如下:'); //while LJCursor.moveToNext do for LRecIndex := 0 to LRecCount-1 do begin //:开始提取缩略图列的数据:getBlob(columnIndex: Integer): TJavaArray<Byte>; //if not LJCursor.isNull(LJCursor.getColumnIndex(StringToJString('_data'))) then //if not LJCursor.isNull(3) then begin {LImgBlobTBytes:=LJCursor.getBlob(1); Memo1.Lines.Add( '_id:'+LJCursor.getInt(0).ToString+',' +'image_id:'+LJCursor.getInt(2).ToString+',' +'kind:'+LJCursor.getInt(3).ToString+',' +'width:'+LJCursor.getInt(4).ToString+',' +'height:'+LJCursor.getInt(5).ToString+',' +'_data:'+JStringToString(LJCursor.getString(1))+',' +'_data的字节长度:'+LImgBlobTBytes.Length.ToString ); } //各记录数值如下: //_id:1, image_id:7604, kind:1, width:480, height:270, //_data:/storage/emulated/0/DCIM/.thumbnails/1569643422581.jpg, _data的字节长度:55 //_data:被分割提取后的文件名:就是时间截13位的其中后3位为毫秒:可用于排序和时间分类,就和手机自带的【图库】一样: //LFilePath_NameArray:=FImgsStringList[LItem.Index].Split(['/']); //LItem.Text:=LFilePath_NameArray[Length(LFilePath_NameArray)-1]; //INC(LRecIndex); L_id:=LJCursor.getInt(0); L_data:=JStringToString(LJCursor.getString(1)); Limage_id:=LJCursor.getInt(2); Lkind:=LJCursor.getInt(3); Lwidth:=LJCursor.getInt(4); Lheight:=LJCursor.getInt(5); LTableStruct_SplitStr:= L_id.ToString+','+L_data.Trim+','+Limage_id.ToString+',' +Lkind.ToString+','+Lwidth.ToString+','+Lheight.ToString; //LIFImageDuplicates:=false; try {for LImagePathInStringList in FImgsStringList do begin if LImagePathInStringList.Trim=L_data.Trim then LIFImageDuplicates:=true; end; //:循环会大大降低执行效率并阻塞界面} //LIFImageDuplicates:=FImgsStringList.Find(L_data,LImageIndex ) //:.Find :在子线程中不生效,只能在UI线程 //:只能在循环外,每次都重新查询后赋值1次:FImgsStringList.Clear finally //if LIFImageDuplicates=false then //FImgsStringList.Add(L_data); //:LImageIndex FImgsStringList.Insert(LRecIndex,LTableStruct_SplitStr); end; if not LJCursor.isLast then LJCursor.moveToNext; end; end; //} if FDefaultRecordCound_PrototypeBindSource<1 then FDefaultRecordCound_PrototypeBindSource:=200; Memo1.Lines.Clear; Memo1.Lines.Add( '缩略图总数: '+FImgsStringList.Count.ToString +' ,默认每页记录数(200),当前从此记录开始加载: '+FDefaultRecordCound_PrototypeBindSource.ToString ); //:循环后记录号:5353,与记录总数吻合 //imgContact.Bitmap.LoadFromFile(JStringToString(LJCursor.getString(1))); //:测试UI加载路径图片 LJCursor.close; end; end; end.
2.2、小结
如上,我们若需要访问Android手机缩略图库,则可以通过:
URI_ContentProvider :=TJImages_Thumbnails.JavaClass.EXTERNAL_CONTENT_URI;
LJCursor :=TJImages_Thumbnails.JavaClass .queryMiniThumbnail(******);
同理访问Android手机原图图库,则可以通过
URI_ContentProvider:=TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI;
LJCursor :=TJImages_Thumbnails.JavaClass .query(******);
来获取。
那么,Android四大组件之ContentProvider的内容提供者,我们还有哪些可在delphiXE中运用的呢?
续本博客博文:《Android四大组件之ContentProvider的内容提供者,我们还有哪些可在delphiXE中运用》:
https://blog.csdn.net/pulledup/article/details/105699037
附注:转好文章:《Android之四大组件、六大布局、五大存储》
喜欢的话,就在下面点个赞、收藏就好了,方便看下次的分享:
-
关于ListView异步加载图片导致图片显示混乱以及ListView效率问题探讨
2012-12-22 15:02:52前面看到有帖子中有人使用notifyDataSetChanged()来解决ListView中异步加载图片第一张图片显示错误问题。首先在数据源没有变化的情况...所以notifyDataSetChanged()在图片都已下载缓存完的情况下正常显示了,但是因为重 -
Android 效率开发之图片---Glide 旋转图片处理
2018-03-19 11:16:32通过Glide 强大的图片变换功能,我们也可以旋转图片,关于Glide 的图片变换请参考:Android图片加载框架最全解析(五),Glide强大的图片变换功能,关于图片旋转请参考 :Android 效率开发之图片旋转处理,图片... -
关于提高AlphaBlend效率的思考
2013-04-02 15:28:15在做UI开发的时候,如果要实现比较漂亮的界面是需要大量用到透明渐变效果及不规则图片的,在前一篇中中曾经总结过要想显示当图像象素具有不同透明度或不规则图形边缘有渐变色需要平滑显示时要用alpha运算,特别是... -
关于oc中遍历的效率算法研究
2017-01-06 15:59:46欢迎使用Markdown编辑器写博客本Markdown编辑器使用[StackEdit][6]...图片链接和图片上传 LaTex数学公式 UML序列图和流程图 离线写博客 导入导出Markdown文件 丰富的快捷键 快捷键 加粗 Ctrl + B 斜体 Ctrl + I 引用 -
关于wangEditor的图片上传失效的解决办法
2018-09-15 17:11:20业务介绍,该编辑器我是在上传数据时用到的,每一条数据都会绑定至少一个或者是一个以上的编辑器,为提高效率,我让其在首页加载时就创建所需的编辑器,也避免了在重新打开一条记录进行上传或修改时... -
关于c 实现希望提高效率的探讨
2010-10-14 22:00:00写了一个图片压缩的程序(yuv420 to jpeg)函数,该函数条用了ffmpeg的库。执行该函数压缩一帧数据的时间是140ms左右的时间,现在压缩3张,如果串行执行的话,需要420左右ms的时间,由于其他原因,现在希望... -
前端:关于图片的研究
2014-12-26 16:33:00css方面 给图片添加边框,padding:1px;...盘-古-建=站的统一用的js等比例缩放图片,并让图片自动居中。 Remarks:有待研究。(20141226) 缺点:浪费浏览器性能,页面效率下降。 编辑运营方面 相... -
图片上传使用post_关于规范上传及使用网站图片的通知
2021-01-28 06:48:29由于各委员会在发布文章时没有按规定上传并使用图片,导致上传的图片得不到重复的利用,使工作效率不高,并浪费协会官方平台流量的问题,特发布本通知。请所有工作团队成员在发布新闻时按本通知要求执行。一、上传... -
关于python3中整数数组转bytes的效率问题
2017-11-26 14:10:06昨天在做一道CTF题的时候碰到了一个图片异或的问题,操作大概如下: 将一个图片读入,然后每字节进行异或操作,核心代码可简化为以下: #coding:utf-8 ''' @DateTime: 2017-11-25 13:51:33 @Version: 1.0 @... -
关于uniapp中分包后无法加载分包中的图片、图片报错500、图片分包以及分包优化的问题
2020-12-13 17:07:42这可能会造成主包的体积过大、影响首页加载效率、超出2M限制等问题,而又不想将图片上传到服务器,这时候可以采用uniapp提供的分包加载机制,本文对如何使用分包加载不做过多介绍,只对 分包后 的图片加载异常做详细... -
百度图片时看到一张很眼熟,竟然是自己发的,这收录效率!
2021-02-24 07:30:42昨天在 CSND 发布了一篇关于 JS 逆向 debugger 的文章,今天继续分析时,在百度的“图片”栏进行相关图片搜索,然后看到了一张特别眼熟的图片,而且其实时间是12小时之前。 -
虚拟桌面分屏_职场效率—关于笔记本电脑分屏操作的小技巧
2021-01-02 21:36:07简单来说就像下面图片一样,将多个程序在同一个电脑屏幕中。曾经为了电脑分屏,我还特意购买了maxto的软件,结果前段时间才发现Windows系统自带分配。电脑分屏可以运用在哪些场景呢?比如写PPT的时候,需要参考WORD... -
关于AE读取点流水文件生成shp点图层效率的问题,
2015-01-13 07:55:07[图片说明](https://img-ask.csdn.net/upload/201501/13/1421135583_41591.png) 由于我的kclswj.fmb中的点大概有12万条,这样循环执行起来特别慢,我初学AE开发,请问有没有高手可以给我指点一下,不胜感激。 -
关于扫描图片或者div移动的CSS处理
2020-01-03 20:19:52做一些前端都会遇到一些,让你做一些效果,比如说上下,左右移动在一...当然你还可以自己写JS,但是自己尝试过,也参照过别人的例子,但是一言难尽,效率不高是一个问题。 那么有没有一种效率高,维护简便的来实现扫... -
android笔记2——关于图片缓存的一些注意事项
2016-04-06 15:36:07当应用页面需要网络加载很多图片的时候,为了提高效率,需要缓存图片,前段时间写了一个需要加载很多网络图片的ListView页面,当时为了提高效率将下载的图片用一个软引用字段进行缓存,但是效果不尽人意,缓存的图片... -
华为怎么分屏操作技巧_职场效率—关于笔记本电脑分屏操作的小技巧
2020-11-09 21:19:57简单来说就像下面图片一样,将多个程序在同一个电脑屏幕中。曾经为了电脑分屏,我还特意购买了maxto的软件,结果前段时间才发现Windows系统自带分配。电脑分屏可以运用在哪些场景呢?比如写PPT的时候,需要参考WORD... -
python 图像识别效率低_请问可以用python实现将大图片变成小图片处理吗,这边要做一个图像识别,太大的...
2020-12-22 23:29:58"云服务器ECS","des":"云服务器(Elastic Compute Service,简称 ECS)是一种简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本,使您更专注于核心业务。... -
为编辑小MM提供的服务代码。关于图片上传的。
2012-11-28 10:01:12我们在工作中遇到了如下场景:编辑小妹需要发布图文混排的内容,图片有点偏多,一篇内容约有20来张图片,一天要发布200多篇,用编辑器自带的图片上传有点效率不够。 目标:提升上传效率. 方法一. 直接上word ... -
关于cocos2dx不同平台图片渲染实现的分析
2014-02-27 10:54:23最近项目中遇到这样一个问题:cocos2dx渲染图片的效率比较低,为了提高渲染效率有几种办法。 1. 多线程进行渲染,cocos2dx 3.0 就采用的这个办法。 2. 在程序启动时,统一进行渲染图片并将渲染的结果放到内存池中,... -
利用gRPC C++传输opencv的mat类型图片-第二种高效率方法---我是搬砖大学生
2019-09-06 08:10:07上次在另外一编文章写了关于利用gRPC c++传输图片的方法。详情请看: https://blog.csdn.net/liyangbinbin/article/details/100538412 但是效率不高,因为无论服务器还是客户端都要进行M*N(图像大小是MxN)次的... -
关于图片保存到数据库中的流程(相对路径)
2016-11-03 14:35:001.常用解决方法是:将图片直接保存在项目的某个目录中,然后将路径(一般是相对路径'images/tuumb1.gif')存储进数据库,这样数据量小。效率高 2.Servlet中的代码 1 public class query extends ... -
图片导入ppt后模糊_【分享】相见恨晚的10个PPT制作小技巧!提高你的PPT制作效率...
2020-12-30 13:50:59楼主也是在学习过程中,今天就抛砖引玉,为大家介绍10个制作PPT的小技巧,减少繁复工作,提高工作效率。1、关于字体:a.替换字体,一键将A字体替换为B字体。这个功能使用起来非常简单,但是如果不会使用,真真的增加... -
关于如何高效率开发一个 Android APP
2016-01-13 17:32:27在这里总结一下,希望帮到有需要的人 网络模块 § okhttp § android-async-http § volley 事件总线 § otto § EventBus ...图片模块 § Fresco § Glide § picasso 数据库模块 § greenDao § or -
使用freetype生成字体图片FireMonkey效率问题
2017-06-26 11:18:18下面是测试代码,经过优化后主要是重设png图像大小,严重影响速度,一万字可能...(其实是两个,其他两个一个是固定的头部信息,一个是固定的尾部信息),关于png分析网上文档很多,不做分析,贴出原始FireMonkey的TBitmap测试代