Я немного потрудился, и кажется, что самый простой способ - либо позволить пользователю выбрать локальный файл, либо использовать захваченное изображение в POST как тип данных, закодированный в Base64, а затем на странице сервера определить,или не был опубликован файл, если было опубликовано закодированное изображение в кодировке Base64.Я добавляю больше кода, который у меня есть.
<form id="uploadavatar" class = "ajaxpostform" data-target ="/user/uploadAvatar_action" method="post" enctype="multipart/form-data">
<label for="avatar_file">Select an avatar image from your hard-disk (will be scaled to 256 x 256 px, only .jpg currently):</label>
<input type="file" accept="image/*" id = "avatar_file" name="avatar_file" />
<!-- max size 5 MB (as many people directly upload high res pictures from their digital cameras) -->
<input type="hidden" name="MAX_FILE_SIZE" value="5000000" />
<input type="submit" value="Upload image" />
</form>
</div>
<div class="box">
<h3>Delete your avatar</h3>
<p>Click this link to delete your (local) avatar: <a id="deleteavatar" class = "ajaxload" data-target = "/user/deleteAvatar_action" href="/user/deleteAvatar_action">Delete your avatar</a>
<video id="player" controls autoplay></video>
<button id="capture">Capture</button>
<button id="savecapture" style="display:none;">Save</button>
<canvas id="canvas" width=320 height=240></canvas>
</div>
</div>
<?php // echo Config::get('URL'); ?>
<script>
const player = document.getElementById('player');
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const captureButton = document.getElementById('capture');
const constraints = {
video: true,
};
captureButton.addEventListener('click', () => {
// Draw the video frame to the canvas.
context.drawImage(player, 0, 0, canvas.width, canvas.height);
// player.srcObject.getVideoTracks().forEach(track => track.stop());
var image = new Image();
image.src = canvas.toDataURL("image/png");
$("#savecapture").show();
$("#savecapture").on("click", function(e) {
$.ajax({
type: "POST",
url: "/user/uploadAvatar_action",
dataType: "html",
data: {
imgBase64: image.src }
}).done(function(data, textStatus, jqXHR) {
$(".ajaxdata").html(data);
}).fail(function( jqXHR, textStatus, errorThrown) {
});
});
});
// Attach the video stream to the video element and autoplay.
navigator.mediaDevices.getUserMedia(constraints)
.then((stream) => {
player.srcObject = stream;
});
</script>
На стороне сервера есть некоторый код, который изначально был написан только для отправки файла.Немного изменил его, чтобы при отправке закодированного изображения Base64 он вызывал функцию generateImage, которая записывает декодированное изображение Base64 в файл temp.png в папке avatars, а затем просто возвращает его в функцию createAvatar.Я использую фреймворк "Огромный" на Github, поэтому я делаю некоторые изменения.Не совсем уверен, как определить, является ли изображение .png, .jpg, .gif и т. Д., Но, похоже, оно работает с веб-камерой Mac.
"Огромный" Framework
public static function createAvatar()
{
// check avatar folder writing rights, check if upload fits all rules
if (self::isAvatarFolderWritable() AND self::validateImageFile()) {
if (isset($_POST['imgBase64'])) {
$image = self::generateImage($_POST['imgBase64']);
}
else {
$image = $_FILES['avatar_file']['tmp_name'];
}
// create a jpg file in the avatar folder, write marker to database
$target_file_path = Config::get('PATH_AVATARS') . Session::get('user_id');
self::resizeAvatarImage($image, $target_file_path, Config::get('AVATAR_SIZE'), Config::get('AVATAR_SIZE'));
self::writeAvatarToDatabase(Session::get('user_id'));
Session::set('user_avatar_file', self::getPublicUserAvatarFilePathByUserId(Session::get('user_id')));
Session::add('feedback_positive', Text::get('FEEDBACK_AVATAR_UPLOAD_SUCCESSFUL'));
}
}
public static function generateImage($img)
{
$folderPath = Config::get('PATH_AVATARS');
$image_parts = explode(";base64,", $img);
$image_type_aux = explode("image/", $image_parts[0]);
$image_type = $image_type_aux[1];
$image_base64 = base64_decode($image_parts[1]);
$file = $folderPath . 'temp.png';
file_put_contents($file, $image_base64);
return $file;
}