精华内容
下载资源
问答
  • 在表格上绘制图片 同时用了两种方法 e.Graphics.FillEllipse e.Graphics.DrawString 添加一个imagelist1 e.Graphics.DrawImage 请问:这样影响效率吗?还是只保留一种?
  • Android里面将图片保存到本地,到网络上搜索了一下,方法都差不多,大同小异,把输入流转换成输出流过程而已。最近工作闲,特把其中两个方法对比一下,看他们的效率如何(找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的迭代以及其他关于效率的一点记录欢迎使用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

    展开全文
  • 关于图片轮播代码选择,度娘了一下 ,貌似有很多种啊。 1.javascript实现 1. 动态移动法,就是把移动前li append到后边来,以此达到轮播效果。 2. 视觉移动法,就是复制容器元素,然后在视觉临界点...
  • 一、常用单元引用 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; 

    第二部分 案例篇

    2.1、直接上代码(内附详细说明):

    2.2、小结


     

    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之四大组件、六大布局、五大存储》

          https://blog.csdn.net/shenggaofei/article/details/52450668?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-13&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-13

    喜欢的话,就在下面点个赞、收藏就好了,方便看下次的分享:

     

    展开全文
  • 前面看到有帖子中有人使用notifyDataSetChanged()来解决ListView中异步加载图片第一张图片显示错误问题。首先在数据源没有变化情况...所以notifyDataSetChanged()在图片都已下载缓存完情况下正常显示了,但是因为重
    前面看到有帖子中有人使用notifyDataSetChanged()来解决ListView中异步加载图片第一张图片显示错误问题。首先在数据源没有变化的情况下没有必要使用notifyDataSetChanged(),会导致调用requestLayout()重绘当前界面的列,就是重新走getView().所以notifyDataSetChanged()在图片都已下载缓存完的情况下正常显示了,但是因为重新刷新界面了导致了效率变低。其实要知道ListView图片混乱都是因为重用了ConvertView,但这个是ListView性能的关键。我们为什么说建议在ListView中使用ViewHolder,按我的理解其一是能够保存ConvertView中各个View的引用,使得不需要每次都findViewById严重影响效率,其二是我们可以拿到View的引用后使用setTag()和getTag()方法,道理跟ConvertView.setTag()和ConvertView.getTag()是一样的。所以在异步加载图片的时候我们给予ImageView一个Tag,在加载完成回调的时候根据这个Tag来判断是否要把图片设置到当前的ImageView中。
    ?
    代码片段,双击复制
    01
    private final ArrayList<View> mActiveImages = new ArrayList<View>();

    ?
    代码片段,双击复制
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                    ViewHolder holder = null;
                    if (convertView == null) {
                            // inflate convertView
                            holder = new ViewHolder();
                            // initial holer,means findViewById
                            convertView.setTag(holder);
                    } else {
                            holder = (ViewHolder)convertView.getTag();
                    }
                    // do your stuff
     
                    // add first then load icon,make sure we have the image holding the icon is contained at mActiveImages
                    mActiveImages.remove(holder.mIcon);
                    mActiveImages.add(holder.mIcon);
                    // set tag to imageview for not messing up the images
                    holder.mIcon.setTag("your tag");
                    // here load Icon
                     
                    return convertView;
            }

    另外要善于利用AbsListView.RecyclerListener接口,使用这个接口可以达到只更新当前界面那些列的图片以及释放其他资源。
    ?
    代码片段,双击复制
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    @Override
            public void onMovedToScrapHeap(View view) {
                    ViewHolder holder = (ViewHolder)view.getTag();
                    mActiveImages.remove(holder.mIcon);
            }
     
            @Override
            public void setIcon(ImageView image, String tag, Drawable drawable) {
                    if (mActiveImages.contains(image) && tag.equals(image.getTag())) {
                            image.setImageDrawable(drawable);
                    }
            }

    以上是我的看法,欢迎指正。
    展开全文
  •  通过Glide 强大的图片变换功能,我们也可以旋转图片,关于Glide 的图片变换请参考:Android图片加载框架最全解析(五),Glide强大的图片变换功能,关于图片旋转请参考 :Android 效率开发之图片旋转处理,图片...
  • 在做UI开发时候,如果要实现比较漂亮界面是需要大量用到透明渐变效果及不规则图片的,在前一篇中中曾经总结过要想显示当图像象素具有不同透明度或不规则图形边缘有渐变色需要平滑显示时要用alpha运算,特别是...
  • 欢迎使用Markdown编辑器写博客本Markdown编辑器使用[StackEdit][6]...图片链接和图片上传 LaTex数学公式 UML序列图和流程图 离线写博客 导入导出Markdown文件 丰富快捷键 快捷键 加粗 Ctrl + B 斜体 Ctrl + I 引用
  • 业务介绍,该编辑器我是在上传数据时用到,每一条数据都会绑定至少一个或者是一个以上编辑器,为提高效率,我让其在首页加载时就创建所需编辑器,也避免了在重新打开一条记录进行上传或修改时...
  • 写了一个图片压缩程序(yuv420 to jpeg)函数,该函数条用了ffmpeg库。执行该函数压缩一帧数据时间是140ms左右时间,现在压缩3张,如果串行执行话,需要420左右ms时间,由于其他原因,现在希望...
  • css方面 给图片添加边框,padding:1px;...盘-古-建=站统一用js等比例缩放图片,并让图片自动居中。 Remarks:有待研究。(20141226) 缺点:浪费浏览器性能,页面效率下降。 编辑运营方面 相...
  • 由于各委员会在发布文章时没有按规定上传并使用图片,导致上传的图片得不到重复的利用,使工作效率不高,并浪费协会官方平台流量的问题,特发布本通知。请所有工作团队成员在发布新闻时按本通知要求执行。一、上传...
  • 昨天在做一道CTF题时候碰到了一个图片异或问题,操作大概如下: 将一个图片读入,然后每字节进行异或操作,核心代码可简化为以下: #coding:utf-8 ''' @DateTime: 2017-11-25 13:51:33 @Version: 1.0 @...
  • 这可能会造成主包的体积过大、影响首页加载效率、超出2M限制等问题,而又不想将图片上传到服务器,这时候可以采用uniapp提供的分包加载机制,本文对如何使用分包加载不做过多介绍,只对 分包后 的图片加载异常做详细...
  • 昨天在 CSND 发布了一篇关于 JS 逆向 debugger 的文章,今天继续分析时,在百度的“图片”栏进行相关图片搜索,然后看到了一张特别眼熟的图片,而且其实时间是12小时之前。
  • 简单来说就像下面图片一样,将多个程序在同一个电脑屏幕中。曾经为了电脑分屏,我还特意购买了maxto软件,结果前段时间才发现Windows系统自带分配。电脑分屏可以运用在哪些场景呢?比如写PPT时候,需要参考WORD...
  • [图片说明](https://img-ask.csdn.net/upload/201501/13/1421135583_41591.png) 由于我kclswj.fmb中点大概有12万条,这样循环执行起来特别慢,我初学AE开发,请问有没有高手可以给我指点一下,不胜感激。
  • 做一些前端都会遇到一些,让你做一些效果,比如说上下,左右移动在一...当然你还可以自己写JS,但是自己尝试过,也参照过别人例子,但是一言难尽,效率不高是一个问题。 那么有没有一种效率高,维护简便来实现扫...
  • 当应用页面需要网络加载很多图片的时候,为了提高效率,需要缓存图片,前段时间写了一个需要加载很多网络图片的ListView页面,当时为了提高效率将下载的图片用一个软引用字段进行缓存,但是效果不尽人意,缓存的图片...
  • 简单来说就像下面图片一样,将多个程序在同一个电脑屏幕中。曾经为了电脑分屏,我还特意购买了maxto软件,结果前段时间才发现Windows系统自带分配。电脑分屏可以运用在哪些场景呢?比如写PPT时候,需要参考WORD...
  • "云服务器ECS","des":"云服务器(Elastic Compute Service,简称 ECS)是一种简单高效、处理能力可弹性伸缩计算服务,帮助您快速构建更稳定、安全应用,提升运维效率,降低 IT 成本,使您更专注于核心业务。...
  • 我们在工作中遇到了如下场景:编辑小妹需要发布图文混排的内容,图片有点偏多,一篇内容约有20来张图片,一天要发布200多篇,用编辑器自带的图片上传有点效率不够。 目标:提升上传效率. 方法一. 直接上word ...
  • 最近项目中遇到这样一个问题:cocos2dx渲染图片的效率比较低,为了提高渲染效率有几种办法。 1. 多线程进行渲染,cocos2dx 3.0 就采用这个办法。 2. 在程序启动时,统一进行渲染图片并将渲染结果放到内存池中,...
  • 上次在另外一编文章写了关于利用gRPC c++传输图片的方法。详情请看: https://blog.csdn.net/liyangbinbin/article/details/100538412 但是效率不高,因为无论服务器还是客户端都要进行M*N(图像大小是MxN)次...
  • 1.常用解决方法是:将图片直接保存在项目某个目录中,然后将路径(一般是相对路径'images/tuumb1.gif')存储进数据库,这样数据量小。效率高 2.Servlet中代码 1 public class query extends ...
  • 楼主也是在学习过程中,今天就抛砖引玉,为大家介绍10个制作PPT小技巧,减少繁复工作,提高工作效率。1、关于字体:a.替换字体,一键将A字体替换为B字体。这个功能使用起来非常简单,但是如果不会使用,真真增加...
  • 在这里总结一下,希望帮到有需要人 网络模块 § okhttp § android-async-http § volley 事件总线 § otto § EventBus ...图片模块 § Fresco § Glide § picasso 数据库模块 § greenDao § or
  • 下面是测试代码,经过优化后主要是重设png图像大小,严重影响速度,一万字可能...(其实是两个,其他两个一个是固定头部信息,一个是固定尾部信息),关于png分析网上文档很多,不做分析,贴出原始FireMonkeyTBitmap测试代

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 499
精华内容 199
关键字:

关于效率的图片