-
怎么看懂手机电路图
2020-08-18 06:40:05这种图,由于它直接体现了电子电路的结构和工作原理,所以一般用在设计、分析电路中。分析电路时,通过识别图纸上所画的各种电路元件符号,以及它们之间的连接方式,就可以了解电路的实际工作时情况。 -
手机Python图形界面教程
2010-09-22 10:16:21『第七课』如何利用上节讲的函数画出一条正弦曲线 『第八课』教你如何利用上节的知识让曲线动起来 『第九课』教你如何移动物体 『第十课』加深一些数学公式在绘图中的应用 『第十一课』游戏初步如何用图片做背景 ... -
-
-
如何简单快速理解web前端技术
2020-05-12 10:40:17web前端,通俗地说就是你在电脑或者手机上浏览网页时所有能看到的东西。你浏览的任何网页可能包括文字、图像、声音、动画或视频。 2.web前端包括什么技术? 结构:由什么组成。以汽车为例,汽车由发动机、座椅、...简单快速了解web前端技术
1.什么是web前端?
web前端,通俗地说就是你在电脑或者手机上浏览网页时所有能看到的东西。你浏览的任何网页可能包括文字、图像、声音、动画或视频。
2.web前端包括什么技术?
结构:由什么组成。以汽车为例,汽车由发动机、座椅、外壳、大灯、轮子、控制按钮等组成。这些部件构成汽车的结构。同理,网页也是由标题、段落、图像、视频等组成,这些东西构成了一个网页的结构。设计一个网页的结构需要用到html技术。
表现:各组成部件长什么样子以及在什么位置。例如,汽车的轮子位于底盘下面,颜色为黑色。当然组成网页的各部件也有自己的样子和位置。比如,一幅图片有宽度和高度,一段文字有颜色和字体的大小等。设计一个网页的表现需要用到css技术。
行为:控制各组成部件的动作。例如,汽车的大灯可以通过控制按钮产生由近光变为远光,通过挂挡可调节汽车的速度。网页中也可以控制一幅图片来产生运动效果。控制一个网页各部件的行为,需要用到javascript技术。
3.学习web前端需要准备什么?
第一、能记住两百个左右的英文单词。web前端的三大技术(html技术,css技术,JavaScript技术)常用的单词也就一两百个。
第二、会使用Windows自带的记事本输入英语字母即可。html代码、css代码和JavaScript代码都可以使用记事本来编写
我收集和整理了很多这方面的视频教程,讲的基本上通俗易懂,充满风趣,有想学这一门技术的小伙伴,可以来学习和搞资源,web开发学习交流,群; 前面926中间338加上675就可以找到我了
4.学习web前端技术的顺序。
html语言用于编写网页的各组成部件,有三个版本html4,xhtml和html5。
css用于编写网页各组成部件的样式。有两个版本css2和css3。
JavaScript用于控制网页各组成部件的动作。
html4 + xhtml + css2 + JavaScript主要用于电脑端页面开发
JavaScript + html5 + css3主要用于手机端页面开发。
建议学习顺序:html4、 xhtml、css2、JavaScript、html5、css3。
-
HQChart使用教程12-如何在K线图上添加弹幕 HQChart使用教程15-分析家语法执行器python版本 HQChart使用教程16-py中使用麦语言指标可视化 HQChart使用教程17-多技术指标独立坐标叠加 HQChart使用教程18-K...
-
AXURE RP 6原型设计精髓=AXURE RP 6 RPOTOTYPING ESSENTIALS
2014-08-03 15:36:41本书全面介绍如何在整个界面设计周期中使用Axure,并结合UX过程的固有迭代特性,为线框图和原型的创建指明方向。本书以一个示例项目为背景依次探讨UX项目的创建流程和Axure的各项功能,如解决业务和技术需求、处理... -
Android程序设计基础
2013-08-03 16:28:041.4 在手机上运行程序 9 1.5 快速阅读指南 9 第2章 基本概念 11 2.1 Android的系统架构 11 2.1.1 Linux内核 11 2.1.2 本机库 12 2.1.3 Android运行时 13 2.1.4 应用程序框架 14 2.1.5 应用程序 15 2.2 它还... -
-
-
HTML5高级程序设计.part1
2012-12-08 16:08:044.6.2 在Goolge Map上显示“我在这里” 92 4.7 小结 93 第5章 Communication API 94 5.1 跨文档消息通信 94 5.1.1 理解源安全 96 5.1.2 跨文档消息通信的浏览器支持情况 97 5.1.3 使用postMessage API 97 ... -
Android 上百实例源码分析以及开源分析 集合打包4
2012-07-10 21:54:03功能可以说很多都是首创,我最喜欢的还是自定义搜索,终于也可以在手机上使用google自定义搜索了,应用自带中文,不过设置中含有部分英文。 本项目有81个目标文件。感兴趣的童靴可以好好研究哟。 7、开源项目... -
完整版《HTML5高级程序设计》4
2012-04-12 14:40:18Brian是一位讲演常客,经常在Web 2.0博览会、AJAXWorld博览会和Web JavaOne等国际性会议上做讲演。 Frank Salim Kaazing的元老级工程师,曾参与过WebSocket网关和客户端策略项目。他毕业于波莫纳学院计算机专业,... -
UI动画简洁,遵循Material Design,在设计动画的时候考虑了很多细节,过渡,层级的变化 交互优雅,实现了优雅的手势交互,智能的嵌套滚动,智能的输入法交互,具体看Demo 适配全面屏,目前适配了小米,华为,谷歌,...
-
JAVA上百实例源码以及开源项目
2016-01-03 17:37:40Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥... -
JAVA上百实例源码以及开源项目源代码
2018-12-11 17:07:42Java生成密钥的实例 1个目标文件 摘要:Java源码,算法相关,密钥 Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、... -
短信交互的上下文分析
2011-05-04 14:13:05通过短信的菜单导航,用户在办理业务时,需要通过短信和服务器进行多次请求交互,如何维护用户的上下文? 短信的Session如何处理? 哪位牛人有类似的项目经验,可以分享一下,谢谢! ... -
Android中手写签名的实现
2018-06-06 09:14:45本篇文章就是介绍如何在手机上进行签名。设计思路在画板上进行签名(其实就是绘制图片),裁剪图片,然后保存到本地相册。效果图代码1.自己参考资料写了一个SignatureView继承View,实现签名public class ...前言
本来这篇文章应该很早就发出来了,因为最近一直在忙项目,直到现在才发出来。本篇文章就是介绍如何在手机上进行签名。
设计思路
在画板上进行签名(其实就是绘制图片),裁剪图片,然后保存到本地相册。
效果图
代码
1.自己参考资料写了一个SignatureView继承View,实现签名
public class SignatureView extends View { // View state private List<TimedPoint> mPoints; private boolean mIsEmpty; private float mLastTouchX; private float mLastTouchY; private float mLastVelocity; private float mLastWidth; private RectF mDirtyRect; // Configurable parameters private int mMinWidth; private int mMaxWidth; private float mVelocityFilterWeight; private OnSignedListener mOnSignedListener; private Paint mPaint = new Paint(); private Path mPath = new Path(); private Bitmap mSignatureBitmap = null; private Canvas mSignatureBitmapCanvas = null; public SignatureView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SignatureView, 0, 0); // Configurable parameters try { mMinWidth = a.getDimensionPixelSize(R.styleable.SignatureView_minWidth, convertDpToPx(3)); mMaxWidth = a.getDimensionPixelSize(R.styleable.SignatureView_maxWidth, convertDpToPx(20)); mVelocityFilterWeight = a.getFloat(R.styleable.SignatureView_velocityFilterWeight, 0.9f); mPaint.setColor(a.getColor(R.styleable.SignatureView_penColor, Color.BLACK)); } finally { a.recycle(); } // Fixed parameters mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeJoin(Paint.Join.ROUND); //mPaint.setStyle(Paint.Style.FILL); //画笔风格 // mPaint.setAntiAlias(true); //抗锯齿 // mPaint.setStrokeWidth(10); //画笔粗细 // mPaint.setTextSize(100); //绘制文字大小,单位px //mPaint.setStrokeWidth(Paint.S); // Dirty rectangle to update only the changed portion of the view mDirtyRect = new RectF(); clear(); } /** * Set the pen color from a given resource. If the resource is not found, * {@link Color#BLACK} is assumed. * * @param colorRes * the color resource. */ public void setPenColorRes(int colorRes) { try { setPenColor(getResources().getColor(colorRes)); } catch (Resources.NotFoundException ex) { setPenColor(getResources().getColor(Color.BLACK)); } } /** * Set the pen color from a given color. * * @param color * the color. */ public void setPenColor(int color) { mPaint.setColor(color); } /** * Set the minimum width of the stroke in pixel. * * @param minWidth * the width in dp. */ public void setMinWidth(float minWidth) { mMinWidth = convertDpToPx(minWidth); } /** * Set the maximum width of the stroke in pixel. * * @param maxWidth * the width in dp. */ public void setMaxWidth(float maxWidth) { mMaxWidth = convertDpToPx(maxWidth); } /** * Set the velocity filter weight. * * @param velocityFilterWeight * the weight. */ public void setVelocityFilterWeight(float velocityFilterWeight) { mVelocityFilterWeight = velocityFilterWeight; } public void clear() { mPoints = new ArrayList<TimedPoint>(); mLastVelocity = 0; mLastWidth = (mMinWidth + mMaxWidth) / 2; mPath.reset(); if (mSignatureBitmap != null) { mSignatureBitmap = null; ensureSignatureBitmap(); } setIsEmpty(true); invalidate(); } @Override public boolean onTouchEvent(MotionEvent event) { if (!isEnabled()) return false; float eventX = event.getX(); float eventY = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: getParent().requestDisallowInterceptTouchEvent(true); mPoints.clear(); mPath.moveTo(eventX, eventY); mLastTouchX = eventX; mLastTouchY = eventY; addPoint(new TimedPoint(eventX, eventY)); case MotionEvent.ACTION_MOVE: resetDirtyRect(eventX, eventY); addPoint(new TimedPoint(eventX, eventY)); break; case MotionEvent.ACTION_UP: resetDirtyRect(eventX, eventY); addPoint(new TimedPoint(eventX, eventY)); getParent().requestDisallowInterceptTouchEvent(true); setIsEmpty(false); break; default: return false; } // invalidate(); invalidate((int) (mDirtyRect.left - mMaxWidth), (int) (mDirtyRect.top - mMaxWidth), (int) (mDirtyRect.right + mMaxWidth), (int) (mDirtyRect.bottom + mMaxWidth)); return true; } @Override protected void onDraw(Canvas canvas) { if (mSignatureBitmap != null) { canvas.drawBitmap(mSignatureBitmap, 0, 0, mPaint); } } public void setOnSignedListener(OnSignedListener listener) { mOnSignedListener = listener; } public boolean isEmpty() { return mIsEmpty; } public Bitmap getSignatureBitmap() { Bitmap originalBitmap = getTransparentSignatureBitmap(); Bitmap whiteBgBitmap = Bitmap.createBitmap(originalBitmap.getWidth(), originalBitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(whiteBgBitmap); canvas.drawColor(Color.WHITE); canvas.drawBitmap(originalBitmap, 0, 0, null); return whiteBgBitmap; } public void setSignatureBitmap(Bitmap signature) { clear(); ensureSignatureBitmap(); RectF tempSrc = new RectF(); RectF tempDst = new RectF(); int dWidth = signature.getWidth(); int dHeight = signature.getHeight(); int vWidth = getWidth(); int vHeight = getHeight(); // Generate the required transform. tempSrc.set(0, 0, dWidth, dHeight); tempDst.set(0, 0, vWidth, vHeight); Matrix drawMatrix = new Matrix(); drawMatrix.setRectToRect(tempSrc, tempDst, Matrix.ScaleToFit.CENTER); Canvas canvas = new Canvas(mSignatureBitmap); canvas.drawBitmap(signature, drawMatrix, null); setIsEmpty(false); invalidate(); } public Bitmap getTransparentSignatureBitmap() { ensureSignatureBitmap(); return mSignatureBitmap; } public Bitmap getTransparentSignatureBitmap(boolean trimBlankSpace) { if (!trimBlankSpace) { return getTransparentSignatureBitmap(); } ensureSignatureBitmap(); int imgHeight = mSignatureBitmap.getHeight(); int imgWidth = mSignatureBitmap.getWidth(); int backgroundColor = Color.TRANSPARENT; int xMin = Integer.MAX_VALUE, xMax = Integer.MIN_VALUE, yMin = Integer.MAX_VALUE, yMax = Integer.MIN_VALUE; boolean foundPixel = false; // Find xMin for (int x = 0; x < imgWidth; x++) { boolean stop = false; for (int y = 0; y < imgHeight; y++) { if (mSignatureBitmap.getPixel(x, y) != backgroundColor) { xMin = x; stop = true; foundPixel = true; break; } } if (stop) break; } // Image is empty... if (!foundPixel) return null; // Find yMin for (int y = 0; y < imgHeight; y++) { boolean stop = false; for (int x = xMin; x < imgWidth; x++) { if (mSignatureBitmap.getPixel(x, y) != backgroundColor) { yMin = y; stop = true; break; } } if (stop) break; } // Find xMax for (int x = imgWidth - 1; x >= xMin; x--) { boolean stop = false; for (int y = yMin; y < imgHeight; y++) { if (mSignatureBitmap.getPixel(x, y) != backgroundColor) { xMax = x; stop = true; break; } } if (stop) break; } // Find yMax for (int y = imgHeight - 1; y >= yMin; y--) { boolean stop = false; for (int x = xMin; x <= xMax; x++) { if (mSignatureBitmap.getPixel(x, y) != backgroundColor) { yMax = y; stop = true; break; } } if (stop) break; } return Bitmap.createBitmap(mSignatureBitmap, xMin, yMin, xMax - xMin, yMax - yMin); } private void addPoint(TimedPoint newPoint) { mPoints.add(newPoint); if (mPoints.size() > 2) { // To reduce the initial lag make it work with 3 mPoints // by copying the first point to the beginning. if (mPoints.size() == 3) mPoints.add(0, mPoints.get(0)); ControlTimedPoints tmp = calculateCurveControlPoints(mPoints.get(0), mPoints.get(1), mPoints.get(2)); TimedPoint c2 = tmp.c2; tmp = calculateCurveControlPoints(mPoints.get(1), mPoints.get(2), mPoints.get(3)); TimedPoint c3 = tmp.c1; Bezier curve = new Bezier(mPoints.get(1), c2, c3, mPoints.get(2)); TimedPoint startPoint = curve.startPoint; TimedPoint endPoint = curve.endPoint; float velocity = endPoint.velocityFrom(startPoint); velocity = Float.isNaN(velocity) ? 0.0f : velocity; velocity = mVelocityFilterWeight * velocity + (1 - mVelocityFilterWeight) * mLastVelocity; // The new width is a function of the velocity. Higher velocities // correspond to thinner strokes. float newWidth = strokeWidth(velocity); // The Bezier's width starts out as last curve's final width, and // gradually changes to the stroke width just calculated. The new // width calculation is based on the velocity between the Bezier's // start and end mPoints. addBezier(curve, mLastWidth, newWidth); mLastVelocity = velocity; mLastWidth = newWidth; // Remove the first element from the list, // so that we always have no more than 4 mPoints in mPoints array. mPoints.remove(0); } } private void addBezier(Bezier curve, float startWidth, float endWidth) { ensureSignatureBitmap(); float originalWidth = mPaint.getStrokeWidth(); float widthDelta = endWidth - startWidth; float drawSteps = (float) Math.floor(curve.length()); for (int i = 0; i < drawSteps; i++) { // Calculate the Bezier (x, y) coordinate for this step. float t = ((float) i) / drawSteps; float tt = t * t; float ttt = tt * t; float u = 1 - t; float uu = u * u; float uuu = uu * u; float x = uuu * curve.startPoint.x; x += 3 * uu * t * curve.control1.x; x += 3 * u * tt * curve.control2.x; x += ttt * curve.endPoint.x; float y = uuu * curve.startPoint.y; y += 3 * uu * t * curve.control1.y; y += 3 * u * tt * curve.control2.y; y += ttt * curve.endPoint.y; // Set the incremental stroke width and draw. mPaint.setStrokeWidth(startWidth + ttt * widthDelta); mSignatureBitmapCanvas.drawPoint(x, y, mPaint); expandDirtyRect(x, y); } mPaint.setStrokeWidth(originalWidth); } private ControlTimedPoints calculateCurveControlPoints(TimedPoint s1, TimedPoint s2, TimedPoint s3) { float dx1 = s1.x - s2.x; float dy1 = s1.y - s2.y; float dx2 = s2.x - s3.x; float dy2 = s2.y - s3.y; TimedPoint m1 = new TimedPoint((s1.x + s2.x) / 2.0f, (s1.y + s2.y) / 2.0f); TimedPoint m2 = new TimedPoint((s2.x + s3.x) / 2.0f, (s2.y + s3.y) / 2.0f); float l1 = (float) Math.sqrt(dx1 * dx1 + dy1 * dy1); float l2 = (float) Math.sqrt(dx2 * dx2 + dy2 * dy2); float dxm = (m1.x - m2.x); float dym = (m1.y - m2.y); float k = l2 / (l1 + l2); TimedPoint cm = new TimedPoint(m2.x + dxm * k, m2.y + dym * k); float tx = s2.x - cm.x; float ty = s2.y - cm.y; return new ControlTimedPoints(new TimedPoint(m1.x + tx, m1.y + ty), new TimedPoint(m2.x + tx, m2.y + ty)); } private float strokeWidth(float velocity) { return Math.max(mMaxWidth / (velocity + 1), mMinWidth); } /** * Called when replaying history to ensure the dirty region includes all * mPoints. * * @param historicalX * the previous x coordinate. * @param historicalY * the previous y coordinate. */ private void expandDirtyRect(float historicalX, float historicalY) { if (historicalX < mDirtyRect.left) { mDirtyRect.left = historicalX; } else if (historicalX > mDirtyRect.right) { mDirtyRect.right = historicalX; } if (historicalY < mDirtyRect.top) { mDirtyRect.top = historicalY; } else if (historicalY > mDirtyRect.bottom) { mDirtyRect.bottom = historicalY; } } /** * Resets the dirty region when the motion event occurs. * * @param eventX * the event x coordinate. * @param eventY * the event y coordinate. */ private void resetDirtyRect(float eventX, float eventY) { // The mLastTouchX and mLastTouchY were set when the ACTION_DOWN motion // event occurred. mDirtyRect.left = Math.min(mLastTouchX, eventX); mDirtyRect.right = Math.max(mLastTouchX, eventX); mDirtyRect.top = Math.min(mLastTouchY, eventY); mDirtyRect.bottom = Math.max(mLastTouchY, eventY); } private void setIsEmpty(boolean newValue) { mIsEmpty = newValue; if (mOnSignedListener != null) { if (mIsEmpty) { mOnSignedListener.onClear(); } else { mOnSignedListener.onSigned(); } } } private void ensureSignatureBitmap() { if (mSignatureBitmap == null) { mSignatureBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); mSignatureBitmapCanvas = new Canvas(mSignatureBitmap); } } private int convertDpToPx(float dp) { return Math.round(dp * (getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT)); } public interface OnSignedListener { public void onSigned(); public void onClear(); } }
2.在Android6.0以后有些权限要动态添加,6.0以下可以在清单文件中添加
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 4); } else { Toast.makeText(this, "已开启权限", Toast.LENGTH_SHORT).show(); } }
回调的方法
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode){ case 4: if(grantResults.length>0 &&grantResults[0] == PackageManager.PERMISSION_GRANTED){ Toast.makeText(this, "已打开权限!", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(this, "请打开权限!", Toast.LENGTH_SHORT).show(); } break; default: } }
3.图片裁剪
public static Bitmap compressScale(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos); if( baos.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出 baos.reset();//重置baos即清空baos image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%,把压缩后的数据存放到baos中 } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); BitmapFactory.Options newOpts = new BitmapFactory.Options(); //开始读入图片,此时把options.inJustDecodeBounds 设回true了 newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 float hh = 800f;//这里设置高度为800f float ww = 480f;//这里设置宽度为480f //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 int be = 1;//be=1表示不缩放 if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放 be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放 be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;//设置缩放比例 //newOpts.inPreferredConfig = Bitmap.Config.RGB_565;//降低图片从ARGB888到RGB565 //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 isBm = new ByteArrayInputStream(baos.toByteArray()); bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); // return compressImage(bitmap);//压缩好比例大小后再进行质量压缩 return bitmap; }
4.签名保存图片
mSaveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Bitmap signatureBitmap = mSignaturePad.getSignatureBitmap(); Bitmap bitmap = compressScale(signatureBitmap); if (addSignatureToGallery(bitmap)) { Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "保存失败", Toast.LENGTH_SHORT).show(); } } });
public void saveBitmapToJPG(Bitmap bitmap, File photo) throws IOException { Bitmap newBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(newBitmap); canvas.drawColor(Color.WHITE); canvas.drawBitmap(bitmap, 0, 0, null); OutputStream stream = new FileOutputStream(photo); newBitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream); stream.close(); } public boolean addSignatureToGallery(Bitmap signature) { boolean result = false; try { final File photo = new File(getAlbumStorageDir("draw"), String.format(creatTime+".jpg", System.currentTimeMillis())); saveBitmapToJPG(signature,photo); Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); Uri contentUri = Uri.fromFile(photo); mediaScanIntent.setData(contentUri); MainActivity.this.sendBroadcast(mediaScanIntent); result = true; } catch (IOException e) { e.printStackTrace(); } return result; }
总结
到这里差不多就已经完成,具体还有一些xml之类的,看demo吧
DEMO
https://download.csdn.net/download/wen_haha/10460115
GitHub
-
产品经理学习视频
2018-07-27 14:21:074-如何绘制流程图.mp4 5-任务流程图.mp4 6-页面流程图.mp4 7-绘制流程图的思路和工具.mp4 8-Axure绘制简单业务流程图.mp4 9-Excel绘制甘特图.mp4 10-Visio绘制泳道图.mp4 11-PPT绘制页面流程图.mp4 12-... -
HQChart使用教程12-如何在K线图上添加弹幕 HQChart使用教程15-分析家语法执行器python版本 HQChart使用教程16-py中使用麦语言指标可视化 HQChart使用教程17-多技术指标独立坐标叠加 HQChart使用教程18-K...
-
C#编程经验技巧宝典
2008-06-01 08:59:3379 <br>0115 如何判断是否为数字 79 <br>0116 如何在字符串中查找指定字符 79 <br>0117 如何在字符串中用一子串替换另一子串 80 <br>0118 将新字符串添加到已有字符串中 80 <br>0119 如何在... -
Google Android SDK开发范例大全(第3版) 1/5
2013-01-20 18:45:35《Google Android SDK开发范例大全(第3版)》在上一版的基础上,以Android手机应用程序开发(采用Android SDK 2.3.3)为主题,超过200多个范例全面且深度地整合了手机、网络及服务等多个开发领域,为读者提高程序设计... -
Google Android SDK开发范例大全(第3版) 4/5
2013-01-20 19:16:09《Google Android SDK开发范例大全(第3版)》在上一版的基础上,以Android手机应用程序开发(采用Android SDK 2.3.3)为主题,超过200多个范例全面且深度地整合了手机、网络及服务等多个开发领域,为读者提高程序设计... -
软件工程教程
2012-07-06 23:10:29这幅画在一副优雅的4x8英尺画布上以画家特有的滴溅泼洒的艺术手法来进行风暴式设计并拨开油彩。 任务1 系统的研发背景 追问:为什么呢? 你好,这里是梦幻家园售楼处,我是蔡小姐。 我是张总,我严重警告你。 为... -
gridview不显示bit_怎样选一块好的显示器(文末附显示器推荐)
2021-01-20 02:24:27之前在评论区收到这样一条留言 相信喜欢电脑绘图的朋友都遇到过这样的问题,电脑上画的画显示得好好的,传到手机上就变得艳俗无比,仿佛刚从十八线影楼出来。同一张图,不同显示器会有不同的色彩显示,对于CG绘画者...之前在评论区收到这样一条留言
相信喜欢电脑绘图的朋友都遇到过这样的问题,电脑上画的画显示得好好的,传到手机上就变得艳俗无比,仿佛刚从十八线影楼出来。
同一张图,不同显示器会有不同的色彩显示,对于CG绘画者和平面设计师来说,拥有一块好的显示器就尤为重要。
专业的显示器才能告诉你,到底哪个颜色才是最真实的,这将直接影响到你的作品呈现,以免出现“你感觉美丽,别人感觉眼瞎”的尴尬。
那么该如何挑选一块不错的显示器呢?有几个关键参数你需要知道——
色域
:表示能显示的色彩范围
在现实世界中自然界的可见光谱颜色组成了最大的色域空间,而显示器所能表达的颜色数量只是其中的一部分。
全世界最为广泛使用的色彩空间就是sRGB(standard Red Green Blue),所以大家也不必过于纠结Adobe RGB色域更广,显示器有99%sRGB就很够用了。
色深
:表示色彩的精细程度
色深建立在色域的基础上,决定同一种颜色到底有多少种灰阶。显示器色深越高,意味着它能带你纵享越丝滑的色彩过渡。
说到色深就不得不提它的单位bit了,几bit就是2的几次方,目前主流设计专业显示器都会达到原生8 bit(1670万色),想上10bit的朋友别太贪心,先考虑一下你的显卡跑不跑得动。
色准
:表示色彩还原的准确性
显示器之所以会偏色,就是色准值deltaE(△E,读作“叼它E”)在捣鬼,也就是你们说的“色差”。
△E越小,色彩精确度就越高。
一般显示器△E值在3以下,肉眼基本就看不出毛区别了,如果有对色彩要求更高的朋友,可以选择△E值<2的屏幕。
看到这里,大家对色域、色深、色准有没有自己的理解了呢?如果你有PS、绘图、摄影方面的需求,那么选择显示器的时候就要重点关注这几项参数。
当然还有分辨率和尺寸这样的基本参数需要考虑,如果买回来发现桌子放不下就很尴尬了,或者桌子深度不够,感觉一直在做头部运动(想象坐电影院第一排)。
以下推荐几款性价比不错的显示器
SANC N50plus
23.8英寸2K分辨率,98%sRGB,8bit,玩游戏也可,最近有活动,券后629能搞到手。
盟达(MENDA)M1-Q2475
23.8英寸2K分辨率,99%sRBG,8bit,底座可旋转升降,屏幕也可旋转90°,价格在799上下。
当然,如果你愿意加一嗲嗲预算的话(恶魔之音),那么戴尔U系列是个不错的选择,戴尔显示器目前在图像设计领域的口碑很好,色彩展示在业内属于一流水平,战翼老师们就人手配备了一台~
战翼基地照
其中U2417H是性价比不错的一款——
边框够窄
上边和左右边框仅5.3毫米,下边框8.3毫米
色彩丰富
99 %sRGB覆盖,△E<2,色彩精准度有保证
广域视角
178°展现精准而一致的色彩和良好的显示效果
拥有它,你就能享受更好的绘画体验,再也不用疯狂导图修改颜色啦,而且画竖图的时候还能把屏幕旋转90°,竖屏处理文档帮你打开新世界的大门!
大家还有什么关于绘画相关的疑问,可以在评论区提问,我们会选取回复并解答。
如果想学习更多关于绘画的知识
欢迎关注微信公众号【战翼CG文化】(ID:zhanyiedu)
获取更多超实用的绘画教程
加入战翼绘画交流群【633591760】,入群链接:战翼插画交流群
在群内结识更多绘画同好,一起进步,学画路上不孤独,等你来玩~
-
ASP.NET开发实战1200例(第1卷).part2
2016-06-11 20:12:37实例071 如何将字节单位B转换成GB、MB 和KB 108 实例072 身份证号从15位升到18位算法 109 第3章 面向对象编程思想 111 3.1 面向对象家族核心——类与类成员 112 实例073 面向对象编程核心——类、对象和引用 112 ... -
ASP.NET开发实战1200例(第1卷).part1
2016-06-11 20:07:19实例071 如何将字节单位B转换成GB、MB 和KB 108 实例072 身份证号从15位升到18位算法 109 第3章 面向对象编程思想 111 3.1 面向对象家族核心——类与类成员 112 实例073 面向对象编程核心——类、对象和引用 112 ... -
ASP.NET开发实战1200例(第1卷).part3
2016-06-11 20:19:00实例071 如何将字节单位B转换成GB、MB 和KB 108 实例072 身份证号从15位升到18位算法 109 第3章 面向对象编程思想 111 3.1 面向对象家族核心——类与类成员 112 实例073 面向对象编程核心——类、对象和引用 112 ... -
《Google Android SDK开发范例大全(第3版)》.pdf
2013-02-17 14:30:16《google android sdk开发范例大全(第3版)》在上一版的基础上,以android手机应用程序开发(采用android sdk 2.3.3)为主题,超过200多个范例全面且深度地整合了手机、网络及服务等多个开发领域,为读者提高程序设计...