iPhone 或安卓上传的照片,可能因横向或纵向拍摄,导致上传后照片显示成 90 度、180 度、270 度角旋转,使用 C# 处理该照片时同样会遇到相同的问题。
解决的方案:
客户端使用 base64 显示图片,可按正常方向显示,且不通过服务端即时显示。关键代码:
$('#file_input').change(function (e) {
if (e.target.files.length == 0) { return; }
// file 转换为 base64
var reader = new FileReader();
reader.readAsDataURL(e.target.files[0]);
reader.onload = function (event) {
$('#myImg').attr('src', event.target.result).css({ width: 'auto', height: 'auto' });
}
});
$('#myImg').on('load', function () {
console.log('图片加载完成')
});
但 base64 字符串传递到服务端受请求大小限制(一般比直接 POST 文件要小)。所以显示图片的同时应即时使用 POST 方式上传图片(如 jquery.fileupload.js)。
当然如果是在微信中打开网页,使用 JS-SDK 的 wx.chooseImage() 返回的 localId 也可以在 <img /> 中正常显示,然后使用 wx.uploadImage() 上传到微信服务器并获取 serverId,在通过获取临时素材接口取回图片文件。
服务端如果需要处理该图片(缩放、裁切、旋转等),需要先读取照片的拍摄角度,旋正后,再进行处理,相关 C# 代码:
/// <summary>
/// 调整照片的原始拍摄旋转角度
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
private Image ImageRotateFlip(Image img)
{
foreach (var prop in img.PropertyItems)
{
if (prop.Id == 0x112)
{
switch (prop.Value[0])
{
case 6: img.RotateFlip(RotateFlipType.Rotate90FlipNone); break;
case 3: img.RotateFlip(RotateFlipType.Rotate180FlipNone); break;
case 8: img.RotateFlip(RotateFlipType.Rotate270FlipNone); break;
}
prop.Value[0] = 1;
}
}
return img;
}

打开文件 Startup.cs,找到:
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TodoApi v1"));
将这两行移出 if 外。

今天发现在开发新项目时,微信分享失效了,开启 debug = true 后,在微信开发工具中提示:
{"errMsg":"updateTimelineShareData:fail, the permission value is offline verifying"}
在真机上提示:
{"errMsg":"config:ok"}
{"errMsg":"updateAppMessageShareData:ok"}
{"errMsg":"updateTimelineShareData"}
仍然找不出原因。
尝试打开已上线的项目,分享功能均正常。
偶然发现,当打开使用 JS-SDK 分享后的图文框的页面,能够正常分享,而直接点开链接的页面,没有分享按钮。
这难免不让人联想到最近GJ出的新政,新版微信已经开放淘宝、抖音等平台的链接打开权限,只是当点击链接的时候会出现一个风险提示页面:
而一旦由这个页面进入的网页,分享功能均不能正常。
另外还测试了以下几种情况的分享功能也能正常:
公众号推送的图文或链接、公众号菜单、个人发送到公众号的链接、通过扫一扫打开的页面等。
-- 2021.9

天地图:https://map.tianditu.gov.cn/
开放平台:http://lbs.tianditu.gov.cn/
控制台:https://console.tianditu.gov.cn/
版本 | 类参考 | 代码示例 |
JavaScript API 4.0 | 类参考 | 代码示例 |
JavaScript API 4.0 开源库 | 资源引用、类参考及示例 |
若不显示地图,请添加域名白名单。
坐标系:CGCS 2000(国家大地坐标系)
版本 | 参考手册 | 示例中心 |
JS API v2 | 参考手册 | 示例中心 |
JS API v1 | 参考手册 | 示例中心 |
更多:坐标获取
坐标系:GCJ-02(火星坐标、国测局坐标系)
控制台:http://lbsyun.baidu.com/apiconsole/center
版本 | 类参考 | 示例DEMO |
JavaScript API GL | 类参考 | 示例DEMO |
JavaScript API v3.0 | 类参考 | 示例DEMO |
更多:拾取坐标系统
坐标系:BD-09(百度坐标)
腾讯地图:https://map.qq.com/
PC端于2022年11月11日停止服务
开放平台(腾讯位置服务):https://lbs.qq.com/
控制台:https://lbs.qq.com/dev/console
版本 | 参考手册 | 示例 |
JavaScript API GL | 参考手册 | 示例 |
更多:位置服务
坐标系:GCJ-02(火星坐标、国测局坐标系)

JavaScript API GL v1.0 是基于 WebGL 全新开发的地图 API 接口。为了方便开发者迁移升级,大部份接口向下兼容。目前 GL v1.0 版本接口包含了 3D 地图的渲染、基本控件、覆盖物。在后面的版本中,将对原 v2.0、v3.0 中的核心功能进行补全。
JavaScript API GL 版本对手机性能要求较高,不建议在移动端调用。若涉及移动端 JS 服务调用,请使用 JavaScript API v3.0 版本。
JavaScript API GL v1.0 基于 WebGL 开发,对于用户的浏览器环境有兼容性要求。需要完整支持 WebGL 的现代浏览器来支持渲染。对于 WebGL 支持欠佳的浏览器会降级为 Canvas 绘制,若仍然存在兼容性问题,则会降级到瓦片图渲染。确保不同浏览器环境的用户都可以完成地图的基本渲染。
参考:http://lbsyun.baidu.com/index.php?title=jspopularGL/guide/usage

类参考:http://lbs.tianditu.gov.cn/api/js4.0/opensource/class/ImageOverlay.html
资源引用:http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/ImageOverlay.js
压缩文件:http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/ImageOverlay.min.js
示例:http://lbs.tianditu.gov.cn/api/js4.0/opensource/demo/ImageOverlay.html
添加图片覆盖物:
map = new T.Map('mapDiv');
map.centerAndZoom(new T.LngLat(116.390750, 39.916980), zoom);
var bd = new T.LngLatBounds(
new T.LngLat(116.385360, 39.911380),
new T.LngLat(116.395940, 39.921400));
img = new T.ImageOverlay("http://lbs.tianditu.gov.cn/images/openlibrary/gugong.jpg", bd, {
opacity: 1,
alt: "故宫博物院"
});
map.addOverLay(img);
修改图片地址:
img.setImageUrl(imgBase64);

百度地图称之为地面叠加层(GroundOverlay)
类参考:https://mapopen-pub-jsapi.bj.bcebos.com/jsapi/reference/jsapi_reference_3_0.html#a3b18
示例DEMO:http://lbsyun.baidu.com/jsdemo.htm#gImageGround
var map = new BMapGL.Map('container');
map.centerAndZoom(new BMapGL.Point(117.200, 36.2437), 18);
map.enableScrollWheelZoom(true);
map.setTilt(45);
map.setDisplayOptions({
poiText: false, // 隐藏poi标注
poiIcon: false, // 隐藏poi图标
building: false // 隐藏楼块
});
var pStart = new BMapGL.Point(117.19635, 36.24093);
var pEnd = new BMapGL.Point(117.20350, 36.24764);
var bounds = new BMapGL.Bounds(new BMapGL.Point(pStart.lng, pEnd.lat), new BMapGL.Point(pEnd.lng, pStart.lat));
var imgOverlay = new BMapGL.GroundOverlay(bounds, {
type: 'image',
url: '/jsdemo/img/shouhuimap.png',
opacity: 1
});
map.addOverlay(imgOverlay);

先上代码:
var db = new db_picContext();
var u = db.DtUser.Find(338);
int a = u.DtProject.Count();
int b = db.DtProject.Count(c => c.UploadUserId == u.Id);
return Json(new { a, b });
运行结果:
{"a":0,"b":2}
是不是说明 Find 结果 u 并不能通过导航属性(外键)来获取关联表的内容?
引擎:Pomelo.EntityFrameworkCore.MySql

示例:
string s = "123456789";
return Json(new
{
// 12
a1 = s.Substring(0, 2),
a2 = s[0..2],
a3 = s[..2],
// 234
b1 = s.Substring(1, 3),
b2 = s[1..4],
// 23456789
c1 = s.Substring(1),
c2 = s.Substring(1, s.Length - 1),
c3 = s[1..],
c4 = s[1..9],
// 123456
d1 = s.Substring(0, s.Length - 3),
d2 = s[0..^3],
d3 = s[..^3],
// 234567
e1 = s.Substring(1, s.Length - 3),
e2 = s[1..^2],
});
Substring(n, m) 取从索引第 n 个字符开始,连续 m 个长度的字符;
范围运算符 [n..m] 取从索引第 n 个字符至索引第 m 个字符前的字符串;
范围运算符 [n..^m] 取从索引第 n 个字符至索引倒数第 m 个字符前的字符串;(在原字符串前再拼接一个同样的字符串,往前数索引更容易理解)
在范围运算符中,当 n 为 0 时可以省略,当 m 为原字符串长度时可以省略。
