Android开源之行之走进zxing,轻松实现二维码扫描(二)

    对于Zxing开源项目的简化上文已给出,源码经过测试且不断修改。众所周知,Zxing项目的扫描是横向的,这么引用的用户体验确实不好;然而盲目的修改会出现拉伸以及样本采集的偏离。所以这里说一下如何将横屏修改为竖屏扫描

    解决办法引用原文:http://blog.csdn.net/aaawqqq/article/details/24804939

 

一、Zxing扫描框架竖屏切换

     1、menifest.xml中,Activitiy必须要设为竖屏的,添加属性

  android:screenOrientation="portrait"

    2、camera扫描过程中,有两个视图:当前扫描view(取景框)和预览preview。为了修正预览的90度的偏离,我们需要修正PreView。因此我们要修改CameraManager中的                        getFramingRectInPreview()的preView的边框

1 rect.left = rect.left * cameraResolution.y / screenResolution.x;
2             rect.right = rect.right * cameraResolution.y / screenResolution.x;
3             rect.top = rect.top * cameraResolution.x / screenResolution.y;
4             rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
View Code

   3、在CameraConfigurationManager中setDesiredCameraParameters()设置我们需要设置的Camera参数,设置preView大小,因此我们我们需要在这里添加                    setDisplayOrientation()来设置camera旋转90度旋转;调用位置:setDesiredCameraParameters()中camera.setParameters(parameters)之前

 1 void setDisplayOrientation(Camera camera, int angle) {
 2 
 3         Method method;
 4         try {
 5             method = camera.getClass().getMethod("setDisplayOrientation",
 6                     new Class[] { int.class });
 7             if (method != null)
 8                 method.invoke(camera, new Object[] { angle });
 9         } catch (Exception e1) {
10             e1.printStackTrace();
11         }
12     }
View Code

  4、在DecodeHandler中,decode(byte[] data, int width, int height)在PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height)之前添加以下代码,防止转化的bitmap与取景框得到的扫描图不一致

1 byte[] rotatedData = new byte[data.length];   
2          for (int y = 0; y < height; y++) {   
3          for (int x = 0; x < width; x++)   
4          rotatedData[x * height + height - y - 1] = data[x + y * width];   
5          }   
6          int tmp = width; // Here we are swapping, that's the difference to #11   
7          width = height;   
8          height = tmp;   
9          data = rotatedData;  
View Code

  5、在CameraConfigurationManager中,initFromCameraParameters(Camera camera)替换为如下代码   

 1 void initFromCameraParameters(Camera camera) {
 2         Camera.Parameters parameters = camera.getParameters();
 3         WindowManager manager = (WindowManager) context
 4                 .getSystemService(Context.WINDOW_SERVICE);
 5         Display display = manager.getDefaultDisplay();
 6         Point theScreenResolution = new Point(display.getWidth(),
 7                 display.getHeight());
 8         screenResolution = theScreenResolution;
 9         Log.i(TAG, "Screen resolution: " + screenResolution);
10 
11         /************** 竖屏更改4 ******************/
12         Point screenResolutionForCamera = new Point();
13         screenResolutionForCamera.x = screenResolution.x;
14         screenResolutionForCamera.y = screenResolution.y;
15 
16         // preview size is always something like 480*320, other 320*480
17         if (screenResolution.x < screenResolution.y) {
18             screenResolutionForCamera.x = screenResolution.y;
19             screenResolutionForCamera.y = screenResolution.x;
20         }
21 
22         cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(
23                 parameters, screenResolutionForCamera);
24         Log.i(TAG, "Camera resolution: " + cameraResolution);
25 
26     }
View Code

 

  非常感谢NDK-baozi的解决方法!

 

二、解决自定义取景框的问题

      Zxing中,在取景框中央的红色扫描线或许跟我们需要的循环移动扫描还有些出入,这就需要我们来自定义属于自己的取景框。实现自定义取景框,我们需要改写ViewfinderView来绘制自  己的View。

      首先需要确定一点,在Zxing源代码中,有两个Rect:一个是frame,通过getFramingRect()取得,这是我们要的取景框的Rect;而另一个previewFrame则是预览视图。我们要做的是以frame为参照物进行我们自己的绘制。

   

    1、绘制描述的文字,也即取景框上方的提示消息      

 1 private void drawStatusText(Canvas canvas, Rect frame, int width) {
 2 
 3         String statusText1 = getResources().getString(
 4                 R.string.viewfinderview_status_text1);
 5         String statusText2 = getResources().getString(
 6                 R.string.viewfinderview_status_text2);
 7         int statusTextSize = 45;
 8         int statusPaddingTop = 180;
 9 
10         paint.setColor(statusColor);
11         paint.setTextSize(statusTextSize);
12 
13         int textWidth1 = (int) paint.measureText(statusText1);
14         canvas.drawText(statusText1, (width - textWidth1) / 2, frame.top
15                 - statusPaddingTop, paint);
16 
17         int textWidth2 = (int) paint.measureText(statusText2);
18         canvas.drawText(statusText2, (width - textWidth2) / 2, frame.top
19                 - statusPaddingTop + 60, paint);
20     }
View Code

     

    2、绘制取景框边角,也即四个角的蓝色拐角

 1 private void drawFrameBounds(Canvas canvas, Rect frame) {
 2 
 3         paint.setColor(Color.WHITE);
 4         paint.setStrokeWidth(2);
 5         paint.setStyle(Paint.Style.STROKE);
 6 
 7         canvas.drawRect(frame, paint);
 8 
 9         paint.setColor(Color.BLUE);
10         paint.setStyle(Paint.Style.FILL);
11 
12         int corWidth = 15;
13         int corLength = 45;
14 
15         // 左上角
16         canvas.drawRect(frame.left - corWidth, frame.top, frame.left, frame.top
17                 + corLength, paint);
18         canvas.drawRect(frame.left - corWidth, frame.top - corWidth, frame.left
19                 + corLength, frame.top, paint);
20         // 右上角
21         canvas.drawRect(frame.right, frame.top, frame.right + corWidth,
22                 frame.top + corLength, paint);
23         canvas.drawRect(frame.right - corLength, frame.top - corWidth,
24                 frame.right + corWidth, frame.top, paint);
25         // 左下角
26         canvas.drawRect(frame.left - corWidth, frame.bottom - corLength,
27                 frame.left, frame.bottom, paint);
28         canvas.drawRect(frame.left - corWidth, frame.bottom, frame.left
29                 + corLength, frame.bottom + corWidth, paint);
30         // 右下角
31         canvas.drawRect(frame.right, frame.bottom - corLength, frame.right
32                 + corWidth, frame.bottom, paint);
33         canvas.drawRect(frame.right - corLength, frame.bottom, frame.right
34                 + corWidth, frame.bottom + corWidth, paint);
35     }
View Code

 

    3、绘制循环移动的扫描线

 1 private void drawScanLight(Canvas canvas, Rect frame) {
 2 
 3         if (scanLineTop == 0) {
 4             scanLineTop = frame.top;
 5         }
 6 
 7         if (scanLineTop >= frame.bottom) {
 8             scanLineTop = frame.top;
 9         } else {
10             scanLineTop += SCAN_VELOCITY;
11         }
12         Rect scanRect = new Rect(frame.left, scanLineTop, frame.right,
13                 scanLineTop + 30);
14         canvas.drawBitmap(scanLight, null, scanRect, paint);
15     }
View Code

 

     通过以上的三步绘制,我们就可以实现展示图的效果。整体的ViewfinderView代码:   

  1 /**
  2  * This view is overlaid on top of the camera preview. It adds the viewfinder
  3  * rectangle and partial transparency outside it, as well as the laser scanner
  4  * animation and result points. 这是一个位于相机顶部的预览view,它增加了一个外部部分透明的取景框,以及激光扫描动画和结果组件
  5  * 
  6  * @author dswitkin@google.com (Daniel Switkin)
  7  */
  8 public final class ViewfinderView extends View {
  9 
 10     private static final int[] SCANNER_ALPHA = { 0, 64, 128, 192, 255, 192,
 11             128, 64 };
 12     private static final long ANIMATION_DELAY = 80L;
 13     private static final int CURRENT_POINT_OPACITY = 0xA0;
 14     private static final int MAX_RESULT_POINTS = 20;
 15     private static final int POINT_SIZE = 6;
 16 
 17     private CameraManager cameraManager;
 18     private final Paint paint;
 19     private Bitmap resultBitmap;
 20     private final int maskColor; // 取景框外的背景颜色
 21     private final int resultColor;// result Bitmap的颜色
 22     private final int laserColor; // 红色扫描线的颜色
 23     private final int resultPointColor; // 特征点的颜色
 24     private final int statusColor; // 提示文字颜色
 25     private int scannerAlpha;
 26     private List<ResultPoint> possibleResultPoints;
 27     private List<ResultPoint> lastPossibleResultPoints;
 28     // 扫描线移动的y
 29     private int scanLineTop;
 30     // 扫描线移动速度
 31     private final int SCAN_VELOCITY = 5;
 32     // 扫描线
 33     Bitmap scanLight;
 34 
 35     public ViewfinderView(Context context, AttributeSet attrs) {
 36         super(context, attrs);
 37 
 38         // Initialize these once for performance rather than calling them every
 39         // time in onDraw().
 40         paint = new Paint(Paint.ANTI_ALIAS_FLAG);
 41         Resources resources = getResources();
 42         maskColor = resources.getColor(R.color.viewfinder_mask);
 43         resultColor = resources.getColor(R.color.result_view);
 44         laserColor = resources.getColor(R.color.viewfinder_laser);
 45         resultPointColor = resources.getColor(R.color.possible_result_points);
 46         statusColor = resources.getColor(R.color.status_text);
 47         scannerAlpha = 0;
 48         possibleResultPoints = new ArrayList<ResultPoint>(5);
 49         lastPossibleResultPoints = null;
 50         scanLight = BitmapFactory.decodeResource(resources,
 51                 R.drawable.scan_light);
 52     }
 53 
 54     public void setCameraManager(CameraManager cameraManager) {
 55         this.cameraManager = cameraManager;
 56     }
 57 
 58     @SuppressLint("DrawAllocation")
 59     @Override
 60     public void onDraw(Canvas canvas) {
 61         if (cameraManager == null) {
 62             return; // not ready yet, early draw before done configuring
 63         }
 64 
 65         // frame为取景框
 66         Rect frame = cameraManager.getFramingRect();
 67         Rect previewFrame = cameraManager.getFramingRectInPreview();
 68         if (frame == null || previewFrame == null) {
 69             return;
 70         }
 71         int width = canvas.getWidth();
 72         int height = canvas.getHeight();
 73 
 74         // Draw the exterior (i.e. outside the framing rect) darkened
 75         // 绘制取景框外的暗灰色的表面,分四个矩形绘制
 76         paint.setColor(resultBitmap != null ? resultColor : maskColor);
 77         canvas.drawRect(0, 0, width, frame.top, paint);// Rect_1
 78         canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint); // Rect_2
 79         canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1,
 80                 paint); // Rect_3
 81         canvas.drawRect(0, frame.bottom + 1, width, height, paint); // Rect_4
 82 
 83         if (resultBitmap != null) {
 84             // Draw the opaque result bitmap over the scanning rectangle
 85             // 如果有二维码结果的Bitmap,在扫取景框内绘制不透明的result Bitmap
 86             paint.setAlpha(CURRENT_POINT_OPACITY);
 87             canvas.drawBitmap(resultBitmap, null, frame, paint);
 88         } else {
 89             // Draw a red "laser scanner" line through the middle to show
 90             // decoding is active
 91             drawFrameBounds(canvas, frame);
 92             drawStatusText(canvas, frame, width);
 93 
 94             // 绘制扫描线
 95             // paint.setColor(laserColor);
 96             // paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
 97             // scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
 98             // int middle = frame.height() / 2 + frame.top;
 99             // canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1,
100             // middle + 2, paint);
101 
102             drawScanLight(canvas, frame);
103 
104             float scaleX = frame.width() / (float) previewFrame.width();
105             float scaleY = frame.height() / (float) previewFrame.height();
106 
107             // 绘制扫描线周围的特征点
108             List<ResultPoint> currentPossible = possibleResultPoints;
109             List<ResultPoint> currentLast = lastPossibleResultPoints;
110             int frameLeft = frame.left;
111             int frameTop = frame.top;
112             if (currentPossible.isEmpty()) {
113                 lastPossibleResultPoints = null;
114             } else {
115                 possibleResultPoints = new ArrayList<ResultPoint>(5);
116                 lastPossibleResultPoints = currentPossible;
117                 paint.setAlpha(CURRENT_POINT_OPACITY);
118                 paint.setColor(resultPointColor);
119                 synchronized (currentPossible) {
120                     for (ResultPoint point : currentPossible) {
121                         canvas.drawCircle(frameLeft
122                                 + (int) (point.getX() * scaleX), frameTop
123                                 + (int) (point.getY() * scaleY), POINT_SIZE,
124                                 paint);
125                     }
126                 }
127             }
128             if (currentLast != null) {
129                 paint.setAlpha(CURRENT_POINT_OPACITY / 2);
130                 paint.setColor(resultPointColor);
131                 synchronized (currentLast) {
132                     float radius = POINT_SIZE / 2.0f;
133                     for (ResultPoint point : currentLast) {
134                         canvas.drawCircle(frameLeft
135                                 + (int) (point.getX() * scaleX), frameTop
136                                 + (int) (point.getY() * scaleY), radius, paint);
137                     }
138                 }
139             }
140 
141             // Request another update at the animation interval, but only
142             // repaint the laser line,
143             // not the entire viewfinder mask.
144             postInvalidateDelayed(ANIMATION_DELAY, frame.left - POINT_SIZE,
145                     frame.top - POINT_SIZE, frame.right + POINT_SIZE,
146                     frame.bottom + POINT_SIZE);
147         }
148     }
149 
150     /**
151      * 绘制取景框边框
152      * 
153      * @param canvas
154      * @param frame
155      */
156     private void drawFrameBounds(Canvas canvas, Rect frame) {
157 
158         paint.setColor(Color.WHITE);
159         paint.setStrokeWidth(2);
160         paint.setStyle(Paint.Style.STROKE);
161 
162         canvas.drawRect(frame, paint);
163 
164         paint.setColor(Color.BLUE);
165         paint.setStyle(Paint.Style.FILL);
166 
167         int corWidth = 15;
168         int corLength = 45;
169 
170         // 左上角
171         canvas.drawRect(frame.left - corWidth, frame.top, frame.left, frame.top
172                 + corLength, paint);
173         canvas.drawRect(frame.left - corWidth, frame.top - corWidth, frame.left
174                 + corLength, frame.top, paint);
175         // 右上角
176         canvas.drawRect(frame.right, frame.top, frame.right + corWidth,
177                 frame.top + corLength, paint);
178         canvas.drawRect(frame.right - corLength, frame.top - corWidth,
179                 frame.right + corWidth, frame.top, paint);
180         // 左下角
181         canvas.drawRect(frame.left - corWidth, frame.bottom - corLength,
182                 frame.left, frame.bottom, paint);
183         canvas.drawRect(frame.left - corWidth, frame.bottom, frame.left
184                 + corLength, frame.bottom + corWidth, paint);
185         // 右下角
186         canvas.drawRect(frame.right, frame.bottom - corLength, frame.right
187                 + corWidth, frame.bottom, paint);
188         canvas.drawRect(frame.right - corLength, frame.bottom, frame.right
189                 + corWidth, frame.bottom + corWidth, paint);
190     }
191 
192     /**
193      * 绘制提示文字
194      * 
195      * @param canvas
196      * @param frame
197      * @param width
198      */
199     private void drawStatusText(Canvas canvas, Rect frame, int width) {
200 
201         String statusText1 = getResources().getString(
202                 R.string.viewfinderview_status_text1);
203         String statusText2 = getResources().getString(
204                 R.string.viewfinderview_status_text2);
205         int statusTextSize = 45;
206         int statusPaddingTop = 180;
207 
208         paint.setColor(statusColor);
209         paint.setTextSize(statusTextSize);
210 
211         int textWidth1 = (int) paint.measureText(statusText1);
212         canvas.drawText(statusText1, (width - textWidth1) / 2, frame.top
213                 - statusPaddingTop, paint);
214 
215         int textWidth2 = (int) paint.measureText(statusText2);
216         canvas.drawText(statusText2, (width - textWidth2) / 2, frame.top
217                 - statusPaddingTop + 60, paint);
218     }
219 
220     /**
221      * 绘制移动扫描线
222      * 
223      * @param canvas
224      * @param frame
225      */
226     private void drawScanLight(Canvas canvas, Rect frame) {
227 
228         if (scanLineTop == 0) {
229             scanLineTop = frame.top;
230         }
231 
232         if (scanLineTop >= frame.bottom) {
233             scanLineTop = frame.top;
234         } else {
235             scanLineTop += SCAN_VELOCITY;
236         }
237         Rect scanRect = new Rect(frame.left, scanLineTop, frame.right,
238                 scanLineTop + 30);
239         canvas.drawBitmap(scanLight, null, scanRect, paint);
240     }
241 
242     public void drawViewfinder() {
243         Bitmap resultBitmap = this.resultBitmap;
244         this.resultBitmap = null;
245         if (resultBitmap != null) {
246             resultBitmap.recycle();
247         }
248         invalidate();
249     }
250 
251     /**
252      * Draw a bitmap with the result points highlighted instead of the live
253      * scanning display.
254      * 
255      * @param barcode
256      *            An image of the decoded barcode.
257      */
258     public void drawResultBitmap(Bitmap barcode) {
259         resultBitmap = barcode;
260         invalidate();
261     }
262 
263     public void addPossibleResultPoint(ResultPoint point) {
264         List<ResultPoint> points = possibleResultPoints;
265         synchronized (points) {
266             points.add(point);
267             int size = points.size();
268             if (size > MAX_RESULT_POINTS) {
269                 // trim it
270                 points.subList(0, size - MAX_RESULT_POINTS / 2).clear();
271             }
272         }
273     }
274 
275 }
View Code

 

转载于:https://www.cnblogs.com/kipMeister/p/4123676.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/359406.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql二进制大文件_Mysql实例Mysql LONGTEXT 类型存储大文件(二进制也可以) (修改+调试+整理)...

《Mysql实例Mysql LONGTEXT 类型存储大文件(二进制也可以) (修改调试整理)》要点&#xff1a;本文介绍了Mysql实例Mysql LONGTEXT 类型存储大文件(二进制也可以) (修改调试整理)&#xff0c;希望对您有用。如果有疑问&#xff0c;可以联系我们。#include "stdafx.h"/…

阿里云mysql创建多个用户_阿里云MySQL创建指定用户访问指定表

欢迎大家关注我的公众号&#xff0c;有问题可以及时和我交流。1.首先进入到root用户环境mysql -uroot -p输入自己的root密码登录。登录成功之后如果表之前已经存在的话就不需要创建&#xff0c;如果表不存在的话使用创建表命令创建。create database table&#xff1b;2.给用户…

自定义实现moveable button

实现的效果图&#xff1a; 自定义MVButton&#xff0c;继承自UIButton. 属性声明如下&#xff1a; property (nonatomic) CGPoint beginPoint; property (nonatomic) BOOL dragEnable;//自定义button对触摸事件进行响应- (void)touchesBegan:(NSSet *)touches withEvent:(UI…

jOOQ星期二:Vlad Mihalcea深入了解SQL和Hibernate

欢迎来到jOOQ Tuesdays系列。 在本系列中&#xff0c;我们每隔一个月的第三个星期二发布一篇文章&#xff0c;从jOOQ的角度采访我们发现该行业令人兴奋的人。 这包括从事SQL&#xff0c;Java&#xff0c;开放源代码以及其他各种相关主题的人员。 我们很高兴在第三版中与Vlad …

GitHub初次使用记录(一)

1、从GitHub上克隆或者复制别人的档案库&#xff1a; 克隆档案库时需要打开本地Git客户端&#xff08;比如GitHub for Windows 和 GitExtesnsion &#xff09;操作。 下面是用GitExtension克隆档案库&#xff1a; 转载于:https://www.cnblogs.com/lxf1117/p/4140048.html

java集成_Java继承

一.继承1.简介&#xff1a;特点&#xff1a;利于代码复用&#xff1b;缩短开发周期。注&#xff1a;子类不能直接访问父类的私有属性满足“A is a B”的关系就可以形成继承关系例&#xff1a;父类&#xff1a;1 packagecom.swpu.animals;23 public classAnimal {4 //属性5 priv…

java猜数字小游戏_Java实现简单猜数字小游戏

本文实例为大家分享了Java实现猜数字游戏的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下完成猜数字游戏需要实现以下几点&#xff1a;获得一个随机数作为“答案数”&#xff1b; 输入数字&#xff0c;与“答案数”作比较(判断大了&#xff0c;小了&#xff0c;相等…

java软件工程师 英文简历_2017java程序员英文简历范文

2017java程序员英文简历范文简历写完以后&#xff0c;再检查一下你的简历是否回答了以下问题&#xff1a;它是否清楚并能够让雇主尽快知道你的能力?是否写清了你的能力?是否写清了你要求这份工作的.基础?有东西可删除吗?尽力完善你的简历直到最好。2017java程序员英文简历范…

写给java web一年左右工作经验的人

摘要 大学就开始学习web&#xff0c;磕磕绊绊一路走过来&#xff0c;当中得到过开源社区很多的帮助&#xff0c;总结了这些年来的技术积累&#xff0c;回馈给开源社区。 ps&#xff1a;图片都是从网上盗。。。感谢原作者。 ps&#xff1a;文字千真万确都是我自己写的。 在此&am…

FlexyPool如何支持Dropwizard Metrics包重命名

介绍 FlexyPool严重依赖Dropwizard &#xff08;以前是Codahale&#xff09;度量标准来监视连接池的使用情况 。 集成到Dropwizard中后&#xff0c;程序包名称必然会被重命名 。 因此&#xff0c;4.0.0版本将使用io.dropwizard.metrics软件包名称代替com.codahale.metrics 。 …

嵌入式Linux学习笔记

一 嵌入式系统定义&#xff1a; 应用于特定环境的硬件体系。 二 两样非常重要的能力&#xff1a; 1. 掌握各种新概念的能力 2. 调试的能力( 包括软件, 硬件 ) 三 需要的基础知识&#xff1a; 1. 操作系统理论基础 2. 数据结构 3. C,C编程语言 4. 汇编语言 5. Linux基…

java string 内存占用_JVM系列之:String,数组和集合类的内存占用大小

简介之前的文章中&#xff0c;我们使用JOL工具简单的分析过String,数组和集合类的内存占用情况&#xff0c;这里再做一次更详细的分析和介绍&#xff0c;希望大家后面再遇到OOM问题的时候不再抱头痛哭&#xff0c;而是可以有章可循&#xff0c;开始吧。数组先看下JOL的代码和输…

maven osgi_OSGi将Maven与Equinox结合使用

maven osgi很长时间以来&#xff0c;我一直在努力理解OSGi的真正含义。 它已经存在很长时间了&#xff0c;但是没有多少人意识到这一点。 它被炒作是一种非常复杂的技术。 这是我为所有Java开发人员简化的尝试。 简而言之&#xff0c; OSGi是一组规范&#xff0c;这些规范支持模…

python中、文件最重要的功能是( )和接收数据_Python基础语法14个知识点大串讲

来源&#xff1a;Python数据之道Python基础语法大串讲Python 是一门面向对象的编程语言&#xff0c;相信这篇文章对于初学者而言应该会有一个比较大的帮助&#xff0c;下面我们将 Python 中常用的基础语法和函数做了一个汇总&#xff0c;满满的干货&#xff0c;供大家学习。1、…

hadoop简单介绍_Hadoop:简单介绍

hadoop简单介绍什么是Hadoop&#xff1a; Hadoop是用Java编写的框架&#xff0c;用于在大型商品硬件群集上运行应用程序&#xff0c;并具有类似于Google File System和MapReduce的功能 。 HDFS是一个高度容错的分布式文件系统&#xff0c;与Hadoop一样&#xff0c;旨在部署在低…

java mvc 案例_springmvc经典案例

本想自己写一下总结&#xff0c;但是发现一篇好文&#xff0c;转发一下&#xff0c;日后自己再做补充&#xff1b;感谢Sunnier&#xff0c;引自&#xff1a;https://www.cnblogs.com/sunniest/p/4555801.htmlSpringMVC学习笔记----一、SpringMVC基础入门&#xff0c;创建一个He…

java泛型方法无参_从头再来:Java泛型(开发必须知道的)

Java泛型老规矩&#xff0c;测试一下&#xff0c;下面的程序能否正常运行&#xff1f;为什么&#xff1f;开头测试题泛型就是实现了参数化类型&#xff0c;也就是代码可以适用于多种类型。泛型是在编译期检查的&#xff0c;在编译期检查类型是否安全。我认为泛型最有用的就是和…

几种常见模式识别算法整理和总结

这学期选了门模式识别的课。发现最常见的一种情况就是&#xff0c;书上写的老师ppt上写的都看不懂&#xff0c;然后绕了一大圈去自己查资料理解&#xff0c;回头看看发现&#xff0c;Ah-ha&#xff0c;原来本质的原理那么简单&#xff0c;自己一開始仅仅只是被那些看似formidab…

fastd java下载_FastReport VCL报表控件

FastReport VCL报表控件是著名的 Delphi 打印控件。含全部源码。支持 Delphi 10.2 Tokyo&#xff0c;FastReport可以在大量的方式报表的创建过程中操纵对象。快速发展的报表和随后的打印&#xff0c;这样的优点&#xff0c;正如预览打印文档的外观。专业版除了报表标准版的功能…

#102030:在30天内运行20 10K来庆祝Java的20年

1995年5月23日是技术史上的重要时刻。 业界似乎并没有意识到当天发布的语言会在未来几年内完全改变技术的格局。 Java将在今年的同一天庆祝20岁生日。 Java 20年&#xff0c;哇&#xff01; 回顾20年前的存储器时代&#xff0c;思考一下Java的发明时间/方式。 万维网专用于精…