iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Android开发基于ArcSoft实现人脸识别的方法是什么
  • 730
分享到

Android开发基于ArcSoft实现人脸识别的方法是什么

2023-06-25 11:06:36 730人浏览 安东尼
摘要

本篇内容主要讲解“Android开发基于ArcSoft实现人脸识别的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android开发基于ArcSoft实现人脸识别的方法是什么”吧!效果

本篇内容主要讲解“Android开发基于ArcSoft实现人脸识别的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android开发基于ArcSoft实现人脸识别的方法是什么”吧!

效果图

Android开发基于ArcSoft实现人脸识别的方法是什么

Android开发基于ArcSoft实现人脸识别的方法是什么

Android开发基于ArcSoft实现人脸识别的方法是什么

Android开发基于ArcSoft实现人脸识别的方法是什么

激活引擎

第一步配置APP_ID和SDK_KEY
 int activeCode = FaceEngine.activeOnline( ChooseFunctionActivity.this, Param.APP_ID, Param.SDK_KEY);
 public static final String APP_ID = "AwY6okHQHxtM92YRYSEqJQwb8cED5huPvYyMhK1w7BSo";   public static final String SDK_KEY = "AF8SaLYtP3ALsmaTR55y9UXaykBZjTtMt5gwCBkUGugh";
第二步:判断是否添加动态链接库(so文件与jar包)
 private boolean checkSoFile(String[] libraries) {        File dir = new File(getApplicationInfo().nativeLibraryDir);        File[] files = dir.listFiles();        if (files == null || files.length == 0) {            return false;        }        List<String> libraryNameList = new ArrayList<>();        for (File file : files) {            libraryNameList.add(file.getName());        }        boolean exists = true;        for (String library : libraries) {            exists &= libraryNameList.contains(library);        }        return exists;    }
第三步:判断是否申明所有权限
protected boolean CheckPermissions(String[] neededPermissions) {        if (neededPermissions == null || neededPermissions.length == 0) {            return true;        }        boolean allGranted = true;        for (String neededPermission : neededPermissions) {            allGranted &= ContextCompat.checkSelfPermission(this, neededPermission) == PackageManager.PERMISSION_GRANTED;        }        return allGranted;    }

激活引擎代码如下

public void ActivationDevice(final View view) {        if (!libraryExists) {            ShowToast(getString(R.string.library_not_found));            return;        }        if (!CheckPermissions(NEEDED_PERMISSIONS)) {            ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS, ACTION_REQUEST_PERMISSIONS);            return;        }        if (view != null) {            view.setClickable(false);        }        Observable.create( new ObservableOnSubscribe<Integer>() {            @Override            public void subscribe(ObservableEmitter<Integer> emitter) {                RuntimeABI runtimeABI = FaceEngine.getRuntimeABI();                Log.i(TAG, "subscribe: getRuntimeABI() " + runtimeABI);                long start = System.currentTimeMillis();                int activeCode = FaceEngine.activeOnline( ChooseFunctionActivity.this, Param.APP_ID, Param.SDK_KEY);                Log.i(TAG, "subscribe cost: " + (System.currentTimeMillis() - start));                emitter.onNext(activeCode);            }        })                .subscribeOn( Schedulers.io())                .observeOn( AndroidSchedulers.mainThread())                .subscribe(new Observer<Integer>() {                    @Override                    public void onSubscribe(Disposable d) {                    }                    @Override                    public void onNext(Integer activeCode) {                        if (activeCode == ErrorInfo.MOK) {                            ShowToast(getString(R.string.activation_succeeded));                        } else if (activeCode == ErrorInfo.MERR_ASF_ALREADY_ACTIVATED) {                            ShowToast(getString(R.string.already_activated));                        } else {                            ShowToast(getString(R.string.active_failed, activeCode));                        }                        if (view != null) {                            view.setClickable(true);                        }                        ActiveFileInfo activeFileInfo = new ActiveFileInfo();                        int res = FaceEngine.getActiveFileInfo(ChooseFunctionActivity.this, activeFileInfo);                        if (res == ErrorInfo.MOK) {                            Log.i(TAG, activeFileInfo.toString());                        }                    }                    @Override                    public void onError(Throwable e) {                        ShowToast(e.getMessage());                        if (view != null) {                            view.setClickable(true);                        }                    }                    @Override                    public void onComplete() {                    }                });    }

人脸比对 1:N

第一步:初始化本地人脸库
FaceServer.getInstance().init(this);
第二步:初始化引擎和相机
public void onGlobalLayout() {        previewView.getViewTreeObserver().removeOnGlobalLayoutListener(this);        if (!CheckPermissions(NEEDED_PERMISSIONS)) {            ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS, ACTION_REQUEST_PERMISSIONS);        } else {            initEngine();            initCamera();        }    }
第三步:初始化引擎
 private void initEngine() {        ftEngine = new FaceEngine();        ftInitCode = ftEngine.init(this, DetectMode.ASF_DETECT_MODE_VIDEO, ConfigUtil.getFtOrient(this),                16, MAX_DETECT_NUM, FaceEngine.ASF_FACE_DETECT);        frEngine = new FaceEngine();        frInitCode = frEngine.init(this, DetectMode.ASF_DETECT_MODE_IMAGE, DetectFaceOrientPriority.ASF_OP_0_ONLY,                16, MAX_DETECT_NUM, FaceEngine.ASF_FACE_RECOGNITION);        flEngine = new FaceEngine();        flInitCode = flEngine.init(this, DetectMode.ASF_DETECT_MODE_IMAGE, DetectFaceOrientPriority.ASF_OP_0_ONLY,                16, MAX_DETECT_NUM, FaceEngine.ASF_LIVENESS);        Log.i(TAG, "initEngine:  init: " + ftInitCode);        if (ftInitCode != ErrorInfo.MOK) {            String error = getString(R.string.specific_engine_init_failed, "ftEngine", ftInitCode);            Log.i(TAG, "initEngine: " + error);            ShowToast(error);        }        if (frInitCode != ErrorInfo.MOK) {            String error = getString(R.string.specific_engine_init_failed, "frEngine", frInitCode);            Log.i(TAG, "initEngine: " + error);            ShowToast(error);        }        if (flInitCode != ErrorInfo.MOK) {            String error = getString(R.string.specific_engine_init_failed, "flEngine", flInitCode);            Log.i(TAG, "initEngine: " + error);            ShowToast(error);        }    }
第四步:活体检测
private void initCamera() {        DisplayMetrics metrics = new DisplayMetrics();        getWindowManager().getDefaultDisplay().getMetrics(metrics);        final FaceListener faceListener = new FaceListener() {            @Override            public void onFail(Exception e) {                Log.e(TAG, "onFail: " + e.getMessage());            }            //请求FR的回调            @Override            public void onFaceFeatureInfoGet(@Nullable final FaceFeature faceFeature, final Integer requestId, final Integer errorCode) {                //FR成功                if (faceFeature != null) {//                    Log.i(TAG, "onPreview: fr end = " + System.currentTimeMillis() + " trackId = " + requestId);                    Integer liveness = liveneSSMap.get(requestId);                    //不做活体检测的情况,直接搜索                    if (!livenessDetect) {                        searchFace(faceFeature, requestId);                    }                    //活体检测通过,搜索特征                    else if (liveness != null && liveness == LivenessInfo.ALIVE) {                        searchFace(faceFeature, requestId);                    }                    //活体检测未出结果,或者非活体,延迟执行该函数                    else {                        if (requestFeatureStatusMap.containsKey(requestId)) {                            Observable.timer(WAIT_LIVENESS_INTERVAL, TimeUnit.MILLISECONDS)                                    .subscribe(new Observer<Long>() {                                        Disposable disposable;                                        @Override                                        public void onSubscribe(Disposable d) {                                            disposable = d;                                            getFeatureDelayedDisposables.add(disposable);                                        }                                        @Override                                        public void onNext(Long aLong) {                                            onFaceFeatureInfoGet(faceFeature, requestId, errorCode);                                        }                                        @Override                                        public void onError(Throwable e) {                                        }                                        @Override                                        public void onComplete() {                                            getFeatureDelayedDisposables.remove(disposable);                                        }                                    });                        }                    }                }                //特征提取失败                else {                    if (increaseAndGetValue(extractErrorRetryMap, requestId) > MAX_RETRY_TIME) {                        extractErrorRetryMap.put(requestId, 0);                        String msg;                        // 传入的FaceInfo在指定的图像上无法解析人脸,此处使用的是RGB人脸数据,一般是人脸模糊                        if (errorCode != null && errorCode == ErrorInfo.MERR_FSDK_FACEFEATURE_LOW_CONFIDENCE_LEVEL) {                            msg = getString(R.string.low_confidence_level);                        } else {                            msg = "ExtractCode:" + errorCode;                        }                        faceHelper.setName(requestId, getString(R.string.recognize_failed_notice, msg));                        // 在尝试最大次数后,特征提取仍然失败,则认为识别未通过                        requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);                        retryRecognizeDelayed(requestId);                    } else {                        requestFeatureStatusMap.put(requestId, RequestFeatureStatus.TO_RETRY);                    }                }            }            @Override            public void onFaceLivenessInfoGet(@Nullable LivenessInfo livenessInfo, final Integer requestId, Integer errorCode) {                if (livenessInfo != null) {                    int liveness = livenessInfo.getLiveness();                    livenessMap.put(requestId, liveness);                    // 非活体,重试                    if (liveness == LivenessInfo.NOT_ALIVE) {                        faceHelper.setName(requestId, getString(R.string.recognize_failed_notice, "NOT_ALIVE"));                        // 延迟 FAIL_RETRY_INTERVAL 后,将该人脸状态置为UNKNOWN,帧回调处理时会重新进行活体检测                        retryLivenessDetectDelayed(requestId);                    }                } else {                    if (increaseAndGetValue(livenessErrorRetryMap, requestId) > MAX_RETRY_TIME) {                        livenessErrorRetryMap.put(requestId, 0);                        String msg;                        // 传入的FaceInfo在指定的图像上无法解析人脸,此处使用的是RGB人脸数据,一般是人脸模糊                        if (errorCode != null && errorCode == ErrorInfo.MERR_FSDK_FACEFEATURE_LOW_CONFIDENCE_LEVEL) {                            msg = getString(R.string.low_confidence_level);                        } else {                            msg = "ProcessCode:" + errorCode;                        }                        faceHelper.setName(requestId, getString(R.string.recognize_failed_notice, msg));                        retryLivenessDetectDelayed(requestId);                    } else {                        livenessMap.put(requestId, LivenessInfo.UNKNOWN);                    }                }            }        };        CameraListener cameraListener = new CameraListener() {            @Override            public void onCameraopened(Camera camera, int cameraId, int displayOrientation, boolean isMirror) {                Camera.Size lastPreviewSize = previewSize;                previewSize = camera.getParameters().getPreviewSize();                drawHelper = new DrawHelper(previewSize.width, previewSize.height, previewView.getWidth(), previewView.getHeight(), displayOrientation                        , cameraId, isMirror, false, false);                Log.i(TAG, "onCameraOpened: " + drawHelper.toString());                // 切换相机的时候可能会导致预览尺寸发生变化                if (faceHelper == null ||                        lastPreviewSize == null ||                        lastPreviewSize.width != previewSize.width || lastPreviewSize.height != previewSize.height) {                    Integer trackedFaceCount = null;                    // 记录切换时的人脸序号                    if (faceHelper != null) {                        trackedFaceCount = faceHelper.getTrackedFaceCount();                        faceHelper.release();                    }                    faceHelper = new FaceHelper.Builder()                            .ftEngine(ftEngine)                            .frEngine(frEngine)                            .flEngine(flEngine)                            .frQueueSize(MAX_DETECT_NUM)                            .flQueueSize(MAX_DETECT_NUM)                            .previewSize(previewSize)                            .faceListener(faceListener)                            .trackedFaceCount(trackedFaceCount == null ? ConfigUtil.getTrackedFaceCount(FaceComparison_RGB.this.getApplicationContext()) : trackedFaceCount)                            .build();                }            }            @Override            public void onPreview(final byte[] nv21, Camera camera) {                if (faceRectView != null) {                    faceRectView.clearFaceInfo();                }                List<FacePreviewInfo> facePreviewInfoList = faceHelper.onPreviewFrame(nv21);                if (facePreviewInfoList != null && faceRectView != null && drawHelper != null) {                    drawPreviewInfo(facePreviewInfoList);                }                reGISterFace(nv21, facePreviewInfoList);                clearLeftFace(facePreviewInfoList);                if (facePreviewInfoList != null && facePreviewInfoList.size() > 0 && previewSize != null) {                    for (int i = 0; i < facePreviewInfoList.size(); i++) {                        Integer status = requestFeatureStatusMap.get(facePreviewInfoList.get(i).getTrackId());                                                if (livenessDetect && (status == null || status != RequestFeatureStatus.SUCCEED)) {                            Integer liveness = livenessMap.get(facePreviewInfoList.get(i).getTrackId());                            if (liveness == null                                    || (liveness != LivenessInfo.ALIVE && liveness != LivenessInfo.NOT_ALIVE && liveness != RequestLivenessStatus.ANALYZING)) {                                livenessMap.put(facePreviewInfoList.get(i).getTrackId(), RequestLivenessStatus.ANALYZING);                                faceHelper.requestFaceLiveness(nv21, facePreviewInfoList.get(i).getFaceInfo(), previewSize.width, previewSize.height, FaceEngine.CP_PAF_NV21, facePreviewInfoList.get(i).getTrackId(), LivenessType.RGB);                            }                        }                                                if (status == null                                || status == RequestFeatureStatus.TO_RETRY) {                            requestFeatureStatusMap.put(facePreviewInfoList.get(i).getTrackId(), RequestFeatureStatus.SEARCHING);                            faceHelper.requestFaceFeature(nv21, facePreviewInfoList.get(i).getFaceInfo(), previewSize.width, previewSize.height, FaceEngine.CP_PAF_NV21, facePreviewInfoList.get(i).getTrackId());//                            Log.i(TAG, "onPreview: fr start = " + System.currentTimeMillis() + " trackId = " + facePreviewInfoList.get(i).getTrackedFaceCount());                        }                    }                }            }            @Override            public void onCameraClosed() {                Log.i(TAG, "onCameraClosed: ");            }            @Override            public void onCameraError(Exception e) {                Log.i(TAG, "onCameraError: " + e.getMessage());            }            @Override            public void onCameraConfigurationChanged(int cameraID, int displayOrientation) {                if (drawHelper != null) {                    drawHelper.setCameraDisplayOrientation(displayOrientation);                }                Log.i(TAG, "onCameraConfigurationChanged: " + cameraID + "  " + displayOrientation);            }        };        cameraHelper = new CameraHelper.Builder()                .previewViewSize(new Point(previewView.getMeasuredWidth(), previewView.getMeasuredHeight()))                .rotation(getWindowManager().getDefaultDisplay().getRotation())                .specificCameraId(rgbCameraID != null ? rgbCameraID : Camera.CameraInfo.CAMERA_FACING_FRONT)                .isMirror(false)                .previewOn(previewView)                .cameraListener(cameraListener)                .build();        cameraHelper.init();        cameraHelper.start();    }

人脸注册

 private void registerFace(final byte[] nv21, final List<FacePreviewInfo> facePreviewInfoList) {        if (registerStatus == REGISTER_STATUS_READY && facePreviewInfoList != null && facePreviewInfoList.size() > 0) {            registerStatus = REGISTER_STATUS_PROCESSING;            Observable.create( new ObservableOnSubscribe<Boolean>() {                @Override                public void subscribe(ObservableEmitter<Boolean> emitter) {                    boolean success = FaceServer.getInstance().registerNv21(FaceComparison_RGB.this, nv21.clone(), previewSize.width, previewSize.height,                            facePreviewInfoList.get(0).getFaceInfo(), "registered" + faceHelper.getTrackedFaceCount());                    emitter.onNext(success);                }            })                    .subscribeOn( Schedulers.computation())                    .observeOn( AndroidSchedulers.mainThread())                    .subscribe(new Observer<Boolean>() {                        @Override                        public void onSubscribe(Disposable d) {                        }                                                @Override                        public void onNext(Boolean success) {                            //String result = success ? "register success!" : "register failed!";                            //ShowToast(result);//                            AlertDialog.Builder builder = new AlertDialog.Builder( FaceComparison_RGB.this );//                            AlertDialog dialog = builder.create();//                            View AlertDialog_View = View.inflate( FaceComparison_RGB.this,R.layout.register_result,null );//                            dialog.setView( AlertDialog_View );//                            dialog.show();                            ShowPopwindows(success);                            registerStatus = REGISTER_STATUS_DONE;                        }                        @Override                        public void onError(Throwable e) {                            e.printStackTrace();                            ShowToast("register failed!");                            ShowFailPopWindows();                            registerStatus = REGISTER_STATUS_DONE;                        }                        @Override                        public void onComplete() {                        }                    });        }    }

切换前置、后置摄像头

public void switchCamera(View view) {        if (cameraHelper != null) {            boolean success = cameraHelper.switchCamera();            if (!success) {                ShowToast(getString(R.string.switch_camera_failed));            } else {                ShowToast(getString(R.string.notice_change_detect_degree));            }        }    }

到此,相信大家对“Android开发基于ArcSoft实现人脸识别的方法是什么”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: Android开发基于ArcSoft实现人脸识别的方法是什么

本文链接: https://www.lsjlt.com/news/304507.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android开发基于ArcSoft实现人脸识别的方法是什么
    本篇内容主要讲解“Android开发基于ArcSoft实现人脸识别的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android开发基于ArcSoft实现人脸识别的方法是什么”吧!效果...
    99+
    2023-06-25
  • Android 实例开发基于ArcSoft实现人脸识别
    目录效果图激活引擎第一步配置APP_ID和SDK_KEY第二步:判断是否添加动态链接库(so文件与jar包)第三步:判断是否申明所有权限人脸比对 1:N第一步:初始化本地人脸库第二步...
    99+
    2022-11-12
  • Android基于虹软(ArcSoft)实现人脸识别
    1、在虹软的开发者中心创建一个自己的应用,将APP_ID与SDK_KEY记录下来,后面会用到。创建完后就可以下载SDK了。 2、下载完后,就可以根据SDK包里的开发说明文档和代码进...
    99+
    2022-11-12
  • Android基于ArcSoft如何实现人脸识别
    小编给大家分享一下Android基于ArcSoft如何实现人脸识别,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在虹软的开发者中心创建一个自己的应用,将APP_I...
    99+
    2023-06-22
  • android人脸识别开发的方法是什么
    在Android上进行人脸识别开发有以下几种方法:1. 使用OpenCV库:OpenCV是一个开源的计算机视觉库,可以用于人脸检测和...
    99+
    2023-10-09
    android
  • 人脸识别java实现的方法是什么
    人脸识别的Java实现方法包括以下几个步骤:1. 图像采集:使用摄像头或者其他图像采集设备采集人脸图像。2. 人脸检测:使用人脸检测...
    99+
    2023-06-05
    人脸识别java java
  • 基于Python的人脸识别功能怎么实现
    这篇文章主要介绍“基于Python的人脸识别功能怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“基于Python的人脸识别功能怎么实现”文章能帮助大家解决问题。一、 人脸检测人脸检测是指从图像...
    99+
    2023-07-05
  • 基于HTML5的人脸识别技术怎么实现
    今天小编给大家分享一下基于HTML5的人脸识别技术怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起...
    99+
    2022-10-19
  • 基于OpenCV和Gradio怎么实现简单的人脸识别
    今天小编给大家分享一下基于OpenCV和Gradio怎么实现简单的人脸识别的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。环境...
    99+
    2023-07-05
  • 在Android 开发中使用camera怎么实现一个人脸识别功能
    这篇文章将为大家详细讲解有关在Android 开发中使用camera怎么实现一个人脸识别功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Android camera实时预览 实时处理,面部...
    99+
    2023-05-31
    android camera
  • Android开发中实现手势识别功能的方法
    Android开发中实现手势识别功能的方法?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。触摸交互中的概念常用事件首先要了解一些常用的事件: ACTION_DOWN:第一个手指按...
    99+
    2023-05-31
    android roi
  • Android应用开发中触摸屏手势识别的实现方法解析
    很多时候,利用触摸屏的Fling、Scroll等Gesture(手势)操作来操作会使得应用程序的用户体验大大提升,比如用Scroll手势在 浏览器中滚屏,用Fling在阅读器中...
    99+
    2022-06-06
    触摸屏 方法 手势识别 手势 Android
  • recorder.js基于Html5录音功能的实现方法是什么
    这篇文章主要讲解了“recorder.js基于Html5录音功能的实现方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“recorder.js基于Ht...
    99+
    2022-10-19
  • php二次开发的实现方法是什么
    在PHP二次开发中,有许多不同的实现方法可以使用。以下是一些常见的实现方法:1. 使用框架:使用现有的PHP框架,如Laravel、...
    99+
    2023-08-24
    php
  • Python基于域相关实现图像增强的方法是什么
    这篇文章主要讲解了“Python基于域相关实现图像增强的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python基于域相关实现图像增强的方法是什么”吧!介绍当在图像上训练深度神经...
    99+
    2023-06-26
  • Golang基于泛化调用与Nacos实现Dubbo代理的方法是什么
    这篇“Golang基于泛化调用与Nacos实现Dubbo代理的方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Gol...
    99+
    2023-07-05
  • PHP开发点餐系统的订单管理功能实现方法是什么?
    PHP开发点餐系统的订单管理功能实现方法是什么?随着外卖和餐饮行业的迅速发展,点餐系统已经成为餐厅不可或缺的一部分。点餐系统的订单管理功能对于餐厅的运营非常重要,它能够对订单进行管理、处理、查询等操作,提高餐厅的效率和服务质量。那么,在PH...
    99+
    2023-11-01
    实现方法 订单管理 点餐系统
  • PHP开发点餐系统的统计报表功能实现方法是什么?
    PHP开发点餐系统的统计报表功能实现方法是什么?随着餐饮行业的快速发展,越来越多的餐厅开始采用点餐系统来提升服务效率和顾客体验。而作为其中重要的一环,统计报表功能对于餐厅管理者来说是非常重要的。它能够帮助管理者了解餐厅的销售情况、菜品的销售...
    99+
    2023-11-01
    PHP开发 - PHP programming 点餐系统 - ordering system 统计报表功能 - stat
  • PHP开发点餐系统的在线点餐功能实现方法是什么?
    PHP开发点餐系统的在线点餐功能实现方法是什么?随着互联网的发展,越来越多的餐饮企业开始注重在线点餐服务的开发。而PHP作为一种广泛应用于Web开发的开源脚本语言,具有开发周期短、开发成本低、可扩展性强等优势,因此成为了很多餐饮企业选择的主...
    99+
    2023-11-01
    PHP 在线点餐 点餐系统
  • PHP开发点餐系统的会员积分功能实现方法是什么?
    随着互联网的快速发展,餐饮行业也逐渐被电子商务所覆盖。餐饮系统的信息化已成为了餐饮行业不可或缺的一部分。在这个激烈的市场竞争中,如何吸引顾客,提高客户忠诚度,是每个餐饮企业需要解决的问题之一。而点餐系统的会员积分功能就是一种解决方案。PHP...
    99+
    2023-11-01
    PHP开发 点餐系统 会员积分功能
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作