Django view to PNG
I'm writing django webapp, and part of it is to generate view and convert it to png image. (any ideas other then below are appreciated). I've looked at some tools to convert "html to png", but there is mainly problem with {%static files and templates. Another approach is to render page using django templates in browser, and take screenshot. It can be done using "chromedriver" + selenium. I was able to do it in my local ubuntu. But on production - all I've got is remote (ssh) access to some linux bash, where my application is hosted. I've created venv, pip-installed selenium and (chromedriver-py or chromedriver-binary). For the second one - it looks like it is closer to start working, but I've got error message: SessionNotCreatedException Message: session not created: probably user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir
Stackoverflow says, that I should somehow put there a path to my chrome installation's user dir, but is there any chrome installation in that console bash of mine?
Any ideas how to move forward ? or any other ideas how to do it? My code:
import chromedriver_binary
def render_to_png(request ):
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--headless") # Run in headless mode (no GUI)
driver = webdriver.Chrome( options=chrome_options)
driver.get("someurl.com")
driver.save_screenshot("x.png")
driver.quit()
return HttpResponse(status=200)
Well here is an elaborated answer which might help:
For using html2canvas in django you can need cdn link: https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js
Client Side Script
<script>
function captureAndUpload() {
const element = document.getElementById('capture-area'); // replace with your html element id or = document.body for whole page
html2canvas(element).then(canvas => {
canvas.toBlob(blob => {
const formData = new FormData();
formData.append('image', blob, 'screenshot.png');
fetch('/upload-image/', { // replace with djgango url
method: 'POST',
body: formData,
headers: {
'X-CSRFToken': getCSRFToken() // include CSRF token if CSRF enabled
}
})
.then(response => response.json())
.then(data => {
console.log('Upload successful:', data);
})
.catch(error => {
console.error('Error uploading image:', error);
});
}, 'image/png');
});
}
// function to get CSRF token
function getCSRFToken() {
const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
return csrfToken;
}
</script>
The button
<button onclick="captureAndUpload()">Capture and Upload</button>
Django server side logic
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.core.files.storage import default_storage
@csrf_exempt # Use this only if CSRF tokens are not included
def upload_image(request):
if request.method == 'POST' and 'image' in request.FILES:
image = request.FILES['image']
file_path = default_storage.save(f'uploads/{image.name}', image)
return JsonResponse({'message': 'Image uploaded successfully', 'file_path': file_path})
return JsonResponse({'error': 'Invalid request'}, status=400)
Urls.py
...
urlpatterns = [
path('upload-image/', upload_image, name='upload-image'),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
One more thing to add in settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'