使用html2canvas时,Google地图屏幕截图无法捕捉标记和标记聚类
我正在做一个使用Flask的Python项目,在这个项目中我用到了谷歌地图API来展示地图。我实现了html2canvas这个脚本,成功捕捉到了地图的画面。但是地图上还有标记(marker),这个标记却没有被捕捉到。所以我尝试使用html2canvasPythonProxy。以下是我在模板gpsDataMap中的JavaScript代码片段:
$(window).load(function(){
$('#saveMap').click(function(){
html2canvas(document.getElementById('map'), {
"logging": true, //Enable log (use Web Console for get Errors and Warnings)
"proxy":"/surveyApp/gpsDataMap/html2canvas-proxy",
useCORS:true,
"onrendered": function(canvas) {
var img = new Image();
img.onload = function() {
img.onload = null;
document.body.appendChild(img);
};
img.onerror = function() {
img.onerror = null;
if(window.console.log) {
window.console.log("Not loaded image from canvas.toDataURL");
} else {
alert("Not loaded image from canvas.toDataURL");
}
};
img.src = canvas.toDataURL("image/png");
}
});
});
});
这是我的Python代码片段:
import os
import datetime
from flask import Flask, request, render_template, redirect, url_for, flash, Response
from flask.json import dumps
from flask import json
from flask import g, Blueprint, session, abort
from flask_principal import Identity, identity_changed, identity_loaded, RoleNeed, AnonymousIdentity
from flask_login import LoginManager, login_user, login_required, logout_user
from app import app
from model.user_info import SurveyForms
from flask.ext.pymongo import PyMongo
from inspect import getmembers, isfunction
import formConfig
import formTree
import fieldChoices
from dashboard import dashboardData
from collections import namedtuple
from pymongo import MongoClient
from flask import request
from html2canvasproxy import * #include html2canvasproxy in your application
import urlparse
import re
surveyApp_module = Blueprint('surveyApp_module', __name__)
app.config['MONGO_HOST'] = 'localhost'
app.config['MONGO_PORT'] = 27017
app.config['MONGO_DBNAME'] = 'survey'
mongo = PyMongo(app)
h2c = None
real_path = os.getcwd() + '/static/images'
virtual_path = '/gpsDataMap/images/'
@surveyApp_module.route('/')
@login_required
def show_formList():
forms = []
forms = [form.form_name for form in SurveyForms.select().where(SurveyForms.organization_name==session['organization_id'])]
# strip .xml from string to compare with returnData
forms = [form.replace('.xml','') for form in forms]
returnData = mongo.db.collection_names()
returnData.pop(returnData.index('system.indexes'))
intersected_forms = list(set(forms).intersection(returnData))
if len(intersected_forms):
return render_template('index_pjj.html', surveyEntries=intersected_forms)
return render_template('index_pjj.html', surveyEntries=['No Survey'])
@surveyApp_module.route('/dashboard', methods=['POST'])
def dashboard():
formName = request.form['whichSurvey']
session['formName'] = formName
formtree = formTree.formParseDict(formName)
returnData = dashboardData(formName, mongo.db)
summaryData = totalSummary(formName, mongo.db)
jsonData = json.dumps(returnData)
return render_template('dashboard.html', formName=formName, formTree=formtree, returnData=returnData, summaryData=summaryData, jsonData=jsonData)
@surveyApp_module.route('/gpsDataView', methods=['POST'])
def gpsDataView():
formName = request.form['whichSurvey']
gpsFields = formConfig.survey[formName]['gpsField']
(location, fieldName, fieldSelection, fieldChoicesList) = "", "", "", []
location = request.form['location']
fieldName = request.form['fieldName']
try:
fieldSelection = request.form['fieldChoices']
except KeyError:
pass
fieldChoicesList = request.form.getlist('fieldChoicesList')
fieldData = commonFunctions.vizFieldList(formName)
totalFieldData = commonFunctions.vizFieldListFull(formName)
locationIdentifiers = fieldChoices.locationFieldChoices(formName, mongo.db)
returnData = gpsVariate.getDataforGPSMap(formName, mongo.db, gpsFields, location, fieldName, fieldSelection, fieldChoicesList)
return render_template('gpsDataMap.html', returnData=returnData, formName=formName, fieldData=fieldData, totalFieldData=totalFieldData, locationIdentifiers=locationIdentifiers)
#Copy html2canvas.js to static folder (If not use cdns)
@surveyApp_module.route('/gpsDataMap/html2canvas.js')
def html2canvas_js():
return app.send_static_file('html2canvas.js')
@surveyApp_module.route('/gpsDataMap/html2canvas-proxy')
def html2canvas_proxy():
print ("is this proxy really calling ");
h2c = html2canvasproxy(request.args.get('callback'), request.args.get('url'))
h2c.userAgent(request.headers['user_agent'])
# import pdb;pdb.set_trace()
if request.referrer is not None:
h2c.referer(request.referrer)
h2c.route(real_path, virtual_path)
r = h2c.result()
# print r['mime']
# print r['data']
return Response(r['data'], mimetype=r['mime'])
# Get images saved by html2canvasproxy
@surveyApp_module.route('/gpsDataMap/html2canvas/images/<image>')
def images(image):
res = html2canvasproxy.resource(real_path, image)
if res is None:
return '', 404
else:
return res['data']
这是我的main.py脚本:
from app import app, db
from auth import *
from admin import admin
from model import *
from view import *
from filters.user_privilege import check_privilege
from filters.form_filter import filter_type
# custom filters
app.jinja_env.filters['check_privilege'] = check_privilege
app.jinja_env.filters['filter_type'] = filter_type
from surveyApp import surveyApp_module
app.register_blueprint(surveyApp_module, url_prefix='/surveyApp')
from view.accounts.login import login_module
app.register_blueprint(login_module)
if __name__ == '__main__':
app.run(port=5555)
在这个过程中,我在控制台中得到了以下信息:
html2canvas: Preload starts: finding background-images html2canvas.js:21
html2canvas: Preload: Finding images html2canvas.js:21
html2canvas: Preload: Done. html2canvas.js:21
html2canvas: start: images: 1 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 2 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 3 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 4 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 5 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 6 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 7 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 8 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 9 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 10 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 11 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 12 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 13 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 14 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 15 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 16 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 17 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 18 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 19 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 20 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 21 / 23 (failed: 0) html2canvas.js:21
html2canvas: start: images: 22 / 23 (failed: 0) html2canvas.js:21
GET http://127.0.0.1:5555/home/bhim/app/surveyApp_bhim/images/a0af53c02bd2f2aed37f1d895edcf3485117c512.png 404 (NOT FOUND) html2canvas.js:2249
html2canvas: start: images: 23 / 23 (failed: 1) html2canvas.js:21
Finished loading images: # 23 (failed: 1) html2canvas.js:21
html2canvas: Error loading background: html2canvas.js:21
html2canvas: Renderer: Canvas renderer done - returning canvas obj
更新:调试器的结果:
folder => images,
timeout => 30,
mimetype => application/javascript,
ua => Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:29.0) Gecko/20100101 Firefox/29.0,
host => 127.0.0.1:5555,
scheme => http,
ref => ,
url => http://www.google.com,
callback => console.log,
default_callback => console.log,
status => 0,
routePath => /static/images/,
savePath => /home/bhim/app/surveyApp_bhim/static/images/,
prefix => htc_,
real_extension => ,
mimes => ['image/bmp', 'image/windows-bmp', 'image/ms-bmp', 'image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'text/html', 'application/xhtml', 'application/xhtml+xml']
更新:谷歌地图的截图
标记没有被捕捉到。
3 个回答
为了保存标记(这是一个针对html2canvas的解决方法):
(来源#1) : http://humaan.com/custom-html-markers-google-maps/
(来源#2) : http://jsfiddle.net/BCr2B/99/
自己制作标记的方法很快也很简单,这样就能避免一些问题。
function HTMLMarker(lat, lng, col) {
this.lat = lat;
this.lng = lng;
this.col = col;
this.pos = new google.maps.LatLng(lat, lng);
}
HTMLMarker.prototype = new google.maps.OverlayView();
HTMLMarker.prototype.onRemove = function() {}
HTMLMarker.prototype.onAdd = function() {}
HTMLMarker.prototype.draw = function() {
var self = this;
var div = this.div;
if(!div) {
div = this.div = document.createElement('div');
div.className = 'marker';
div.style.position = 'absolute';
div.style.width = '32px';
div.style.height = '32px';
switch(this.col) {
case "green":
div.innerHTML = '<img src="/images/green-dot.png">';
break;
case "yellow":
div.innerHTML = '<img src="/images/yellow-dot.png">';
break;
case "red":
div.innerHTML = '<img src="/images/red-dot.png">';
break;
}
var panes = this.getPanes();
panes.overlayImage.appendChild(div);
}
var position = this.getProjection().fromLatLngToDivPixel(this.pos);
div.style.left = position.x - 16 + "px";
div.style.top = position.y - 32 + "px";
}
然后只需添加:
var htmlMarker = new HTMLMarker(data[gps].Latitude, data[gps].Longitude, "green");
markersArray.push(htmlMarker.setMap(map));
以这种方式导出时,地图标记会成功添加,因为它们来自本地源。
请先试试这个,可能对你有用。
<script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyDY0kkJiTPVd2U7aTOAwhc9ySH6oHxOIYM&sensor=false">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.js"></script>
<script type="text/javascript" src ="http://code.jquery.com/jquery-1.9.0.min.js"></script>
<script type="text/javascript" src="html2canvas.js?rev032"></script>
<script type="text/javascript">
function initialize()
{
var mapProp = {
center:new google.maps.LatLng(51.508742,-0.120850),
zoom:5,
mapTypeId:google.maps.MapTypeId.ROADMAP
};
var map=new google.maps.Map(document.getElementById("googleMap"), mapProp);
}
google.maps.event.addDomListener(window, 'load', initialize);
$(window).load(function(){
$('#load').click(function(){
html2canvas($('#googleMap'), {
useCORS: true,
onrendered: function (canvas) {
var dataUrl= canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
window.location.href = dataUrl;
}
});
});
});
</script>
</head>
<body>
<div id="googleMap" style="width:500px;height:380px;"></div>
<input type="button" value="Save" id="load"/>
</body>
1) 使用 useCORS:true
或者使用 proxy
,但不要同时使用这两者。
2) 你的路由设置不一样,看看:
virtual_path = '/gpsDataMap/images/'
@surveyApp_module.route('/gpsDataMap/html2canvas/images/<image>')
3) 你的代理路由在JavaScript中似乎有问题:
"proxy":"/surveyApp/gpsDataMap/html2canvas-proxy",
@surveyApp_module.route('/gpsDataMap/html2canvas-proxy')
你没有意识到所有的错误,为什么 userCORS
和 "PROXY" 会搞混。
修正所有的路由(路由就是它们的虚拟路径)并修正你的JavaScript(不要使用 userCORS:
),看看:
$(window).load(function(){
$('#saveMap').click(function(){
html2canvas(document.getElementById('map'), {
"logging": true, //Enable log (use Web Console for get Errors and Warnings)
//useCORS:true, "COMMENTED", remove useCORS
"proxy": YOUR_FIXED_ROUTE,
"onrendered": function(canvas) {
var img = new Image();
img.onload = function() {
img.onload = null;
document.body.appendChild(img);
};
img.onerror = function() {
img.onerror = null;
if(window.console.log) {
window.console.log("Not loaded image from canvas.toDataURL");
} else {
alert("Not loaded image from canvas.toDataURL");
}
};
img.src = canvas.toDataURL("image/png");
}
});
});
});
看,这个是绝对路径和“路由”混在一起了:
GET http://127.0.0.1:5555/home/bhim/app/surveyApp_bhim/images/a0af53c02bd2f2aed37f1d895edcf3485117c512.png 404 (NOT FOUND) html2canvas.js:2249
代理响应的路由因为某种原因是错误的,使用这个:
1) 修改你的代码,像这样:
@surveyApp_module.route('/gpsDataMap/html2canvas-proxy')
def html2canvas_proxy():
print ("is this proxy really calling ");
h2c = html2canvasproxy(request.args.get('callback'), request.args.get('url'))
h2c.userAgent(request.headers['user_agent'])
if request.referrer is not None:
h2c.referer(request.referrer)
if request.args.get('debug_vars'): #Added
return Response((',\n'.join(h2c.debug_vars())), mimetype='text/plain') #Added
h2c.route(real_path, virtual_path)
r = h2c.result()
return Response(r['data'], mimetype=r['mime'])
2) 在浏览器中运行:
http://127.0.0.1:5000/gpsDataMap/html2canvas-proxy?callback=console.log&url=http://www.google.com&debug_vars=1
3) 获取结果并在你的问题中发布。