这几天犯了一个错误,初期想着甩锅给后台的… 但还好及时发现了是自身的问题~

关联文章

  • Android基础进阶 - 调用拍照、获取图片(基础)
  • Android基础进阶 - 获取、调用相册内图片(基础)
  • Android进阶之路 - 拍照、相册选图
  • Android进阶之路 - 解决部分手机拍照之后图片被旋转的问题
  • Android进阶之路 - Uri、Path、File、Bitmap 转换方式

Hint:底部扩展了腾讯某个项目内用到的ImageUtil,可以很好的解决图片旋转、压缩、保存的问题

  • 拍照、相册、图片回传
  • 野生 PhotoBitmapUtils
  • 腾讯 ImageUtil

整篇思考

  • 产生问题:通过拍照或相册回传的照片,直接传入后台,在用于展示的时候,照片角度出现问题,均不规则的旋转了90度,从而导致体验效果变差!

  • 问题思考:后台一般都是你怎么存的,它怎么给你拿出来!所以在这里就可以发现问题本身是由我们前端造成的!

  • 覆盖范围:图片被旋转的情况并不是百分百出现在每个机型上,只是会出现在某一部分机型之上,但是本着兼容的原则,我们只有逐个处理

  • 解决方法:找了大约五篇博文左右,我找到了最懒也是最简单有效的方法,主要来自此篇文章,之所以没有转载而且署名原创的原因是因为更全面记录自己遇到的问题、场景、思路~

拍照、相册、图片回传

主要代码部分,已全局进行了注释 (os:我想不会有比我还笨的人,加油把~)

  • 拍照
    /*** 拍照*/private void takePhoto() {//拍照时存储的照片路径,最好提为全局变量,因为成功回传后需要使用到~String photoPath = Environment.getExternalStorageDirectory().getPath() + "/picture_dow_" + SystemClock.currentThreadTimeMillis() + ".jpg";Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);intent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(InfoActivity.this, "com.bakheet.garage.fileprovider", sdcardTempFile));} else {intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(sdcardTempFile));}startActivityForResult(intent, 1);}
  • 相册选取
   /*** 从相册选取照片*/private void selectFromGallery() {Intent intent = new Intent();intent.setAction(Intent.ACTION_PICK);intent.setType("image/*");startActivityForResult(intent, 2);}
  • 重写onActivityResult(此时照片已经回传,我们在这里进行图片处理)
    @Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);switch (requestCode) {//拍照回传case 1:if (resultCode == RESULT_OK && sdcardTempFile.exists()) {//主要通过PhotoBitmapUtils内的amendRotatePhoto方法保存我们拍照时的照片状态String newPath = PhotoBitmapUtils.amendRotatePhoto(photoPath, this);//此时的图片file就是正确的了~final File newSdcardTempFile = new File(newPath);//这个方法是用于传入后台的,可忽略!!!uploadImage(newSdcardTempFile);}break;//相册回传case 2:ContentResolver contentResolver = getContentResolver();if (data != null) {//图片的UUri uri = data.getData();if (uri!=null){//使用工具类获取绝对路径String path = ToolUtil.getFilePathFromContentUri(uri, contentResolver);if (resultCode == RESULT_OK && sdcardTempFile.exists()) {//主要通过PhotoBitmapUtils内的amendRotatePhoto方法保存我们的照片状态String newPath = PhotoBitmapUtils.amendRotatePhoto(photoPath, this);//此时的图片file就是正确的了~final File newSdcardTempFile = new File(newPath);//这个方法是用于传入后台的,可忽略!!!uploadImage(newSdcardTempFile);}}}break;default:break;}}

野生 PhotoBitmapUtils

(主要工具类):

/*** 集合一些图片工具** Created by zhuwentao on 2016-07-22.*/
public class PhotoBitmapUtils {/*** 存放拍摄图片的文件夹*/private static final String FILES_NAME = "/MyPhoto";/*** 获取的时间格式*/public static final String TIME_STYLE = "yyyyMMddHHmmss";/*** 图片种类*/public static final String IMAGE_TYPE = ".png";// 防止实例化private PhotoBitmapUtils() {}/*** 获取手机可存储路径** @param context 上下文* @return 手机可存储路径*/private static String getPhoneRootPath(Context context) {// 是否有SD卡if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)|| !Environment.isExternalStorageRemovable()) {// 获取SD卡根目录return context.getExternalCacheDir().getPath();} else {// 获取apk包下的缓存路径return context.getCacheDir().getPath();}}/*** 使用当前系统时间作为上传图片的名称** @return 存储的根路径+图片名称*/public static String getPhotoFileName(Context context) {File file = new File(getPhoneRootPath(context) + FILES_NAME);// 判断文件是否已经存在,不存在则创建if (!file.exists()) {file.mkdirs();}// 设置图片文件名称SimpleDateFormat format = new SimpleDateFormat(TIME_STYLE, Locale.getDefault());Date date = new Date(System.currentTimeMillis());String time = format.format(date);String photoName = "/" + time + IMAGE_TYPE;return file + photoName;}/*** 保存Bitmap图片在SD卡中* 如果没有SD卡则存在手机中** @param mbitmap 需要保存的Bitmap图片* @return 保存成功时返回图片的路径,失败时返回null*/public static String savePhotoToSD(Bitmap mbitmap, Context context) {FileOutputStream outStream = null;String fileName = getPhotoFileName(context);try {outStream = new FileOutputStream(fileName);// 把数据写入文件,100表示不压缩mbitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);return fileName;} catch (Exception e) {e.printStackTrace();return null;} finally {try {if (outStream != null) {// 记得要关闭流!outStream.close();}if (mbitmap != null) {mbitmap.recycle();}} catch (Exception e) {e.printStackTrace();}}}/*** 把原图按1/10的比例压缩** @param path 原图的路径* @return 压缩后的图片*/public static Bitmap getCompressPhoto(String path) {BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = false;options.inSampleSize = 10;  // 图片的大小设置为原来的十分之一Bitmap bmp = BitmapFactory.decodeFile(path, options);options = null;return bmp;}/*** 处理旋转后的图片* @param originpath 原图路径* @param context 上下文* @return 返回修复完毕后的图片路径*/public static String amendRotatePhoto(String originpath, Context context) {// 取得图片旋转角度int angle = readPictureDegree(originpath);// 把原图压缩后得到Bitmap对象Bitmap bmp = getCompressPhoto(originpath);;// 修复图片被旋转的角度Bitmap bitmap = rotaingImageView(angle, bmp);// 保存修复后的图片并返回保存后的图片路径return savePhotoToSD(bitmap, context);}/*** 读取照片旋转角度** @param path 照片路径* @return 角度*/public static int readPictureDegree(String path) {int degree = 0;try {ExifInterface exifInterface = new ExifInterface(path);int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);switch (orientation) {case ExifInterface.ORIENTATION_ROTATE_90:degree = 90;break;case ExifInterface.ORIENTATION_ROTATE_180:degree = 180;break;case ExifInterface.ORIENTATION_ROTATE_270:degree = 270;break;}} catch (IOException e) {e.printStackTrace();}return degree;}/*** 旋转图片* @param angle 被旋转角度* @param bitmap 图片对象* @return 旋转后的图片*/public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {Bitmap returnBm = null;// 根据旋转角度,生成旋转矩阵Matrix matrix = new Matrix();matrix.postRotate(angle);try {// 将原始图片按照旋转矩阵进行旋转,并得到新的图片returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);} catch (OutOfMemoryError e) {}if (returnBm == null) {returnBm = bitmap;}if (bitmap != returnBm) {bitmap.recycle();}return returnBm;}
}

腾讯 ImageUtil

扩展 - 腾讯部分项目用到的ImageUtil

ImageUtil

package com.tencent.qcloud.tuicore.util;import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.ExifInterface;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;import com.tencent.qcloud.tuicore.TUIConfig;
import com.tencent.qcloud.tuicore.TUILogin;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;public class ImageUtil {public final static String SP_IMAGE = "_conversation_group_face";/*** @param outFile 图片的目录路径* @param bitmap* @return*/public static File storeBitmap(File outFile, Bitmap bitmap) {// 检测是否达到存放文件的上限if (!outFile.exists() || outFile.isDirectory()) {outFile.getParentFile().mkdirs();}FileOutputStream fOut = null;try {outFile.deleteOnExit();outFile.createNewFile();fOut = new FileOutputStream(outFile);bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);fOut.flush();} catch (IOException e1) {outFile.deleteOnExit();} finally {if (null != fOut) {try {fOut.close();} catch (IOException e) {e.printStackTrace();outFile.deleteOnExit();}}}return outFile;}public static Bitmap getBitmapFormPath(Uri uri) {Bitmap bitmap = null;try {InputStream input = TUIConfig.getAppContext().getContentResolver().openInputStream(uri);BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();onlyBoundsOptions.inJustDecodeBounds = true;onlyBoundsOptions.inDither = true;//optionalonlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optionalBitmapFactory.decodeStream(input, null, onlyBoundsOptions);input.close();int originalWidth = onlyBoundsOptions.outWidth;int originalHeight = onlyBoundsOptions.outHeight;if ((originalWidth == -1) || (originalHeight == -1))return null;//图片分辨率以480x800为标准float hh = 800f;//这里设置高度为800ffloat ww = 480f;//这里设置宽度为480fint degree = getBitmapDegree(uri);if (degree == 90 || degree == 270) {hh = 480;ww = 800;}//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可int be = 1;//be=1表示不缩放if (originalWidth > originalHeight && originalWidth > ww) {//如果宽度大的话根据宽度固定大小缩放be = (int) (originalWidth / ww);} else if (originalWidth < originalHeight && originalHeight > hh) {//如果高度高的话根据宽度固定大小缩放be = (int) (originalHeight / hh);}if (be <= 0)be = 1;//比例压缩BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();bitmapOptions.inSampleSize = be;//设置缩放比例bitmapOptions.inDither = true;//optionalbitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optionalinput = TUIConfig.getAppContext().getContentResolver().openInputStream(uri);bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);input.close();compressImage(bitmap);bitmap = rotateBitmapByDegree(bitmap, degree);} catch (Exception e) {e.printStackTrace();}return bitmap;//再进行质量压缩}public static Bitmap getBitmapFormPath(String path) {if (TextUtils.isEmpty(path)) {return null;}return getBitmapFormPath(Uri.fromFile(new File(path)));}public static Bitmap compressImage(Bitmap image) {ByteArrayOutputStream baos = new ByteArrayOutputStream();image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中int options = 100;while (baos.toByteArray().length / 1024 > 100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩baos.reset();//重置baos即清空baos//第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差  ,第三个参数:保存压缩后的数据的流image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中options -= 10;//每次都减少10}ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片return bitmap;}/*** 读取图片的旋转的角度*/public static int getBitmapDegree(Uri uri) {int degree = 0;try {// 从指定路径下读取图片,并获取其EXIF信息ExifInterface exifInterface = new ExifInterface(FileUtil.getPathFromUri(uri));// 获取图片的旋转信息int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);switch (orientation) {case ExifInterface.ORIENTATION_ROTATE_90:degree = 90;break;case ExifInterface.ORIENTATION_ROTATE_180:degree = 180;break;case ExifInterface.ORIENTATION_ROTATE_270:degree = 270;break;}} catch (IOException e) {e.printStackTrace();}return degree;}/*** 读取图片的旋转的角度*/public static int getBitmapDegree(String fileName) {int degree = 0;try {// 从指定路径下读取图片,并获取其EXIF信息ExifInterface exifInterface = new ExifInterface(fileName);// 获取图片的旋转信息int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);switch (orientation) {case ExifInterface.ORIENTATION_ROTATE_90:degree = 90;break;case ExifInterface.ORIENTATION_ROTATE_180:degree = 180;break;case ExifInterface.ORIENTATION_ROTATE_270:degree = 270;break;}} catch (IOException e) {e.printStackTrace();}return degree;}/*** 将图片按照某个角度进行旋转** @param bm     需要旋转的图片* @param degree 旋转角度* @return 旋转后的图片*/public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {Bitmap returnBm = null;// 根据旋转角度,生成旋转矩阵Matrix matrix = new Matrix();matrix.postRotate(degree);try {// 将原始图片按照旋转矩阵进行旋转,并得到新的图片returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);} catch (OutOfMemoryError e) {}if (returnBm == null) {returnBm = bm;}if (bm != returnBm) {bm.recycle();}return returnBm;}public static int[] getImageSize(String path) {int size[] = new int[2];try {BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();onlyBoundsOptions.inJustDecodeBounds = true;BitmapFactory.decodeFile(path, onlyBoundsOptions);int originalWidth = onlyBoundsOptions.outWidth;int originalHeight = onlyBoundsOptions.outHeight;//size[0] = originalWidth;//size[1] = originalHeight;int degree = getBitmapDegree(path);if (degree == 0) {size[0] = originalWidth;size[1] = originalHeight;} else {//图片分辨率以480x800为标准float hh = 800f;//这里设置高度为800ffloat ww = 480f;//这里设置宽度为480fif (degree == 90 || degree == 270) {hh = 480;ww = 800;}//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可int be = 1;//be=1表示不缩放if (originalWidth > originalHeight && originalWidth > ww) {//如果宽度大的话根据宽度固定大小缩放be = (int) (originalWidth / ww);} else if (originalWidth < originalHeight && originalHeight > hh) {//如果高度高的话根据宽度固定大小缩放be = (int) (originalHeight / hh);}if (be <= 0)be = 1;BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();bitmapOptions.inSampleSize = be;//设置缩放比例bitmapOptions.inDither = true;//optionalbitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optionalBitmap bitmap = BitmapFactory.decodeFile(path, bitmapOptions);bitmap = rotateBitmapByDegree(bitmap, degree);size[0] = bitmap.getWidth();size[1] = bitmap.getHeight();}} catch (Exception e) {e.printStackTrace();}return size;}// 图片文件先在本地做旋转,返回旋转之后的图片文件路径public static String getImagePathAfterRotate(final Uri uri) {try {InputStream is = TUIConfig.getAppContext().getContentResolver().openInputStream(uri);Bitmap originBitmap = BitmapFactory.decodeStream(is, null, null);int degree = ImageUtil.getBitmapDegree(uri);if (degree == 0) {return FileUtil.getPathFromUri(uri);} else {Bitmap newBitmap = ImageUtil.rotateBitmapByDegree(originBitmap, degree);String oldName = FileUtil.getFileName(TUIConfig.getAppContext(), uri);File newImageFile = FileUtil.generateFileName(oldName, FileUtil.getDocumentCacheDir(TUIConfig.getAppContext()));if (newImageFile == null) {return FileUtil.getPathFromUri(uri);}ImageUtil.storeBitmap(newImageFile, newBitmap);newBitmap.recycle();return newImageFile.getAbsolutePath();}} catch (FileNotFoundException e) {return FileUtil.getPathFromUri(uri);}}/*** 转换图片成圆形** @param bitmap 传入Bitmap对象* @return*/public static Bitmap toRoundBitmap(Bitmap bitmap) {int width = bitmap.getWidth();int height = bitmap.getHeight();float roundPx;float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;if (width <= height) {roundPx = width / 2;left = 0;top = 0;right = width;bottom = width;height = width;dst_left = 0;dst_top = 0;dst_right = width;dst_bottom = width;} else {roundPx = height / 2;float clip = (width - height) / 2;left = clip;right = width - clip;top = 0;bottom = height;width = height;dst_left = 0;dst_top = 0;dst_right = height;dst_bottom = height;}Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(output);final int color = 0xff424242;final Paint paint = new Paint();final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom);final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom);final RectF rectF = new RectF(dst);paint.setAntiAlias(true);// 设置画笔无锯齿canvas.drawARGB(0, 0, 0, 0); // 填充整个Canvaspaint.setColor(color);// 以下有两种方法画圆,drawRounRect和drawCircle// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);// 画圆角矩形,第一个参数为图形显示区域,第二个参数和第三个参数分别是水平圆角半径和垂直圆角半径。canvas.drawCircle(roundPx, roundPx, roundPx, paint);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));// 设置两张图片相交时的模式canvas.drawBitmap(bitmap, src, dst, paint); //以Mode.SRC_IN模式合并bitmap和已经draw了的Circlereturn output;}/*** 根据图片 UUID 和 类型得到图片文件路径** @param uuid      图片 UUID* @param imageType 图片类型 V2TIMImageElem.V2TIM_IMAGE_TYPE_THUMB , V2TIMImageElem.V2TIM_IMAGE_TYPE_ORIGIN ,*                  V2TIMImageElem.V2TIM_IMAGE_TYPE_LARGE* @return 图片文件路径*/public static String generateImagePath(String uuid, int imageType) {return TUIConfig.getImageDownloadDir() + uuid + "_" + imageType;}public static String getGroupConversationAvatar(String groupId) {SharedPreferences sp = TUIConfig.getAppContext().getSharedPreferences(TUILogin.getSdkAppId() + SP_IMAGE, Context.MODE_PRIVATE);final String savedIcon = sp.getString(groupId, "");if (!TextUtils.isEmpty(savedIcon) && new File(savedIcon).isFile() && new File(savedIcon).exists()) {return savedIcon;}return "";}public static void setGroupConversationAvatar(String conversationId, String url) {SharedPreferences sp = TUIConfig.getAppContext().getSharedPreferences(TUILogin.getSdkAppId() + SP_IMAGE, Context.MODE_PRIVATE);SharedPreferences.Editor editor = sp.edit();editor.putString(conversationId, url);boolean success = editor.commit();if (!success) {Log.e("ImageUtil", "setGroupConversationAvatar failed , id : " + conversationId + " , url : " + url);}}
}

Android进阶之路 - 解决部分手机拍照之后图片被旋转的问题相关推荐

  1. Android开发 调用系统相机相册图片功能,解决小米手机拍照或者图片横竖相反问题,及小米手机相册图片路径问题

    Android开发 调用系统相机相册图片功能,解决小米手机拍照或者图片横竖相反问题,及小米手机相册图片路径问题 1.调用相机,兼容7.0 AndroidManifest配置 <providera ...

  2. android华为获取相册,解决华为手机获取相册图片路径为null

    最近代码君遇到一个问题,在其他手机调用系统相册获取图片路径都是可以的,但是华为手机,执行相同代码,会报空指针异常,网上找了很多资料,都没什么实用的效果 Intent intent; intent = ...

  3. android上传图片被旋转,解决android有的手机拍照后上传图片被旋转的问题

    需求:做仿新浪发微博的项目,能够上传图片还有两外一个项目用到手机拍摄图片,这两个都需要把图片上传到服务器 遇到问题:有的手机拍摄的图片旋转90度,有的图片旋转了180度,有的手机是正常的,服务器要求的 ...

  4. Android进阶之路 - 批量下载、缓存图片

    在日常项目开发中,关于图片批量下载,数据缓存的相关功能比比皆是,这次也是去年在项目中需要在本地缓存商品数据,所以用到了批量下载的功能,特此记录 ~ 关联篇 Android进阶之路 - 批量下载.缓存图 ...

  5. Android 头像替换,解决华为手机取不到图片

    只用涉及到用户模块的App基本上就会用到头像替换的功能,类似的代码也是信手沾来,百度.GitHub以及各大论坛好博客一大把,随便粘过来就可以用了.但是...有坑.在华为荣耀手机上踩坑了,网上看了下问的 ...

  6. Android进阶之路 - 批量下载、缓存图片、视频

    之前已经记录过,批量下载图片和缓存本地的方式,此篇主要记录批量下载图片.视频,同时缓存在本地的功能实现 关联篇 Android进阶之路 - 批量下载.缓存图片 Android进阶之路 - 批量下载.缓 ...

  7. Android进阶之路 - 软键盘中右下角的设置与监听

    在项目中,多多少少会遇到修改软键盘右下角按钮的需求,虽然已经写过几次,但是还是觉得在这里专心做个笔记比较放心 ~ 我的那些软键盘Blog ~ Android进阶之路 - 常见软键盘操作行为 Andro ...

  8. Android进阶之路 - 存、取、读 本地 Json 文件

    最近在开发中又开始加载一些本地的json数据源,回头看之前竟然没记录,赶紧记录一波 ~ 如何准备一个合格的json文件? AndoridStudio中如何存放json文件? 如何读取本地Json文件数 ...

  9. 解决android有的手机拍照后上传图片被旋转的问题

    需求:做仿新浪发微博的项目,能够上传图片还有两外一个项目用到手机拍摄图片,这两个都需要把图片上传到服务器 遇到问题:有的手机拍摄的图片旋转90度,有的图片旋转了180度,有的手机是正常的,服务器要求的 ...

最新文章

  1. NutzWk 5.2.0 重磅发布,Java 微服务分布式开发框架
  2. 设计模式之桥接模式实例
  3. tensorflow从入门到精通100讲(五)-知识图谱( Knowledge Graph)关系抽取之PCNN
  4. proteus 8.4安装教程
  5. SpringMVC的数据响应-页面跳转-返回字符串形式(应用)
  6. How does model reference pass from app view to master view
  7. 关于如何将轮播图在移动端和pc端自适应的操作
  8. 【AI视野·今日Robot 机器人论文速览 第九期】Thu, 17 Jun 2021
  9. RTFM? 如何写一本值得一读的手册
  10. matlab grp2idx,求教:m-fold cross validation 在matlab下如何实现?
  11. 【VS开发】VS2010 MFC中控件、对话框等背景颜色动态修改的方法
  12. Structs个人适用知识整理
  13. hadoop视频教程下载链接汇总
  14. “我爱淘”冲刺阶段Scrum站立会议9
  15. linux超级管理员密码设置
  16. sue的小球 牛客(区间dp)
  17. 传奇GEE引擎版本架设
  18. 使用runOnUiThread更新UI
  19. 【顶】(与同事合作的快乐)技术人员也需要先学会做人,再学会做事,再是能成事,最后是成名得利...
  20. 探索C++0x: 1. 静态断言(static_assert)

热门文章

  1. 未名企鹅极客 | 人机图灵测试中数字图像处理方法研究
  2. uniapp-商品详情配置
  3. IP地址转换函数 inet_pton、inet_ntop与 inet_aton、inet_addr、 inet_ntoa
  4. python卡通滤镜_纯Python综合图像处理小工具(3)10种滤镜算法
  5. 有哪些简洁的人生建议?
  6. qt 修改.exe文件图标_如何在没有错误的情况下更改压缩的.EXE文件上的图标
  7. 你今天好帅用计算机,华师表白墙 | 计算机系最帅的男孩子,我喜欢你!
  8. 云计算安全测评:云应用安全
  9. [UE4][Blueprint]虚幻4实现照相机拍照功能
  10. 支付系统 java_PaySystem