将blob图像恢复为文件

问题描述 投票:0回答:1

我有问题将图像转换为blob并返回到文件,我的意思是当我将图像转换为blob并在页面上显示时,选择我要保留的内容以及要删除的内容并在尝试转换回文件后追加到表单数据,没有任何内容附加到formData和blob图像上的新文件的文件类型和大小是不同的,我该如何更改?谢谢

$(document).on('click', '#addProduct', function(e) {
		e.preventDefault();
		var arr = [];
			for(var q=0; q<$('.image-buttons').length; q++) {
				var blob = $('.image-buttons').children('img').attr('src');
				var fileOfBlob = new File([blob], 'image'+q);
				arr.push(fileOfBlob);
			}
		if(arr.length < 4 && arr.length > 0){
			var formData = new FormData();

			$.each(arr, function(i, file) {
			    formData.append('images', file);
			    console.log(file);
			});
			
			console.log(formData);
			return false;
		}
	});

	$(document).on('change', '#images', function() {
		var reg = /\.(gif|jpg|png|GIF|JPG|PNG|jpeg|JPEG)$/i;
		var imageNameArray = [];
		for(var j = 0; j<$("#images")[0].files.length; j++) {
			if(!$("#images")[0].files[j].name.match(reg)){
				imageNameArray.push($("#images")[0].files[j].name);
			}
		}
		if(imageNameArray.length === 0 && $("#images")[0].size<2097152){
			for(var e=0; e<$("#images")[0].files.length; e++) {
				$('.img-button-holder').append('<div class="image-buttons"><img src="'+window.URL.createObjectURL($("#images")[0].files[e])+'"><div class="img-tools"><i class="fa fa-angle-double-left" aria-hidden="true"></i><i class="fa fa-angle-double-right" aria-hidden="true"></i><i class="fa fa-times removeImg" aria-hidden="true"></i></div></div>');
			}
			$('.image-display').append('<img src="'+window.URL.createObjectURL($("#images")[0].files[0])+'">');
		}
	});

	$(document).on('click', '.image-buttons', function() {
		var this_img = $(this).children('img').attr('src');
		$('.image-buttons').css('border','1px solid #e0e0e0');
		$(this).css('border','2px solid red');
		$('.image-display').children('img').attr('src', this_img);
	});

	$(document).on('click', '.img-tools > .fa', function() {
		var this_el = $(this).parent().parent();
		if($(this).hasClass('removeImg')){
			$(this_el).remove();
		}else if($(this).hasClass('fa-angle-double-left')) {
			var prev = $(this_el).prev();
			$(this_el).insertBefore(prev);
		}else if($(this).hasClass('fa-angle-double-right')) {
			var next = $(this_el).next();
			$(this_el).insertAfter(next);
		}
	});
.addNew {
	width: 100%;
	height: auto;
	float: left;
}

.addNew > form {
	width: 40%;
	float: left;
	height: auto;
	margin-right: 5%;
}

.addNew > .image-display {
	width: 55%;
	float: right;
	min-height: 300px;
	height: auto;
	border: 1px solid #e0e0e0;
	position: relative;
}

.addNew .image-buttons {
	width: 30%;
	height: 80px;
	margin: 10px 1.5%;
	border: 1px solid #e0e0e0;
	float: left;
	overflow: hidden;
	position: relative;
}

.img-button-holder {
	width: 55%;
	float: right;
}

.image-buttons > img, .image-display > img {
	width: 100%;
	height: 100%;
	min-height: 100%;
	min-width: 100%;
}

.image-display > img {
	width: 100%;
	height: auto;
	min-height: auto;
	min-width: 100%;
	position: absolute;
	bottom: 0; left: 0;
}

.img-tools {
	color: red;
	font-size: 2rem;
	position: absolute;
	width: 100%;
	height: auto;
	top: 0; left: 0;
}

.img-tools > i {
	float: left;
	width: 30%;
	margin: 5px 1.5%;
	cursor: pointer;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="addNew">
<form>
<input type="file" name="images" id="images" multiple>
<button id="addProduct">Add</button>
</form>

<div class="image-display"></div>
<div class="img-button-holder"></div>
</div>
javascript jquery html blob multipartform-data
1个回答
0
投票

blobURI(你在代码中误称为blob)只是一个字符串。 您创建的File对象只是text / plain文件中的字符串。

您不必从文件转换为blobURI到文件。

只需保留初始文件,将它们存储在一个好的数组中,然后从那里管理它们。

创建blobURI只显示这些文件(它实际上只是内存中的指针,因此您的文档(此处为<img>)知道如何访问用户磁盘上的文件,因此无法共享)。

当您需要发送文件时,simoly会从您管理的数组中获取它们。

ps:请注意,根据您的后端,您可能必须在formData密钥的名称后附加[]

function sendToServer() {

  var formData = new FormData(),
    files = fileHandler.list; // grab them directly from our manager
  // it's an Array, so use Array methods
  files.forEach(function(file) {
    // since you are on php, to be able to append multiple items in the same field,
    // you need to append '[]' at the end of your fieldName
    formData.append('images[]', file);
  });
  // send it to your server
  var xhr = new XMLHttpRequest();
  xhr.open('POST', 'your_php_script');
  //	xhr.send(formData);
  // but from SO we will just show what's inside
  if (typeof formData.getAll === 'function') {
    console.log(formData.getAll('images[]'));
  }

}
// A basic file manager which will expose its selected files in an Array
function FileHandler(options) {
  if (!options || typeof options !== 'object')
    options = {};

  this.options = options;
  // this is really the only important part: we use an Array to store all our files
  this.list = [];

  this.addButton = isValidElement(options.addButton) || $('<button>', {
    text: 'Add new Files'
  });
  // also, we use a single file input
  this.input = $('<input>', $.extend(options.input || {}, {
    type: 'file',
    class: 'fh-input',
    multiple: true,
  }));

  this.items_container = isValidElement(options.items_container) || $('<div>', {
    class: 'fh-item-container'
  });

  this.preview = this.initPreview();

  this.addButton.on('click', function() {
    this.input.click()
  }.bind(this));
  this.input.on('change', this.onchange.bind(this));

  this.items_container.on('click', '.fh-item .fh-remove', this.remove.bind(this));
  this.items_container.on('click', '.fh-item :not(.fh-remove)', this.handleItemClick.bind(this));
  this.items_container.on('load', 'img', revokeURL);

  // We don't need blobURIs for anything else than loading <img> elements,
  // so we can revoke them directly at load
  function revokeURL(evt) {
    var url = evt.currentTarget.src;
    URL.revokeObjectURL(url);
  }

  function isValidElement(obj) {
    var $obj = $(obj);
    return $obj[0] && $obj[0] instanceof Element && $obj.eq(0);
  }
}
FileHandler.prototype = Object.create({
  add: function addFile(file) {
    if (!(file instanceof Blob))
      throw new TypeError('Argument 1 must be Blob or a File');
    var $item = this.generateItem(file);
    this.items_container.append($item);
    // store it in our Array
    this.list.push(file);
    this.preview.show(file);
    return $item;
  },
  remove: function removeFile(event) {
    var $target = $(event.currentTarget),
      $item = $target.parents('.fh-item').eq(0),
      file = $item.data('fh.file'),
      index = this.list.indexOf(file);

    $item.remove();
    if (index > -1) {
      // remove it from our Array
      this.list.splice(index, 1);
    }

    if (this.preview.current === file) {
      if (this.list.length) {
        var next = index <= (this.list.length - 1) ? index : 0;
        this.preview.show(this.list[next]);
      } else this.preview.hide();
    }
  },
  generateItem: function generateItem(file) {
    if (!(file instanceof Blob))
      throw new TypeError('Argument 1 must be Blob or a File');
    var $cont = $('<div>', {
        class: 'fh-item'
      }),
      $title = $('<span>', {
        text: file.name || 'unknown-file (' + file.type + ')',
        class: 'fh-file_name'
      }),
      $btn = $('<button>', {
        class: 'fh-remove',
        text: 'x',
        title: 'remove',
        name: 'remove item'
      }),
      $thumb = $('<div>', {
        class: 'fh-thumb'
      })
      // a single time blobURI
      .append($('<img>', {
        src: URL.createObjectURL(file)
      }));

    $cont.data('fh.file', file);

    return $cont.append(
      $title,
      $btn,
      $thumb
    );
  },
  onchange: function oninputchange(evt) {
    // retrieve the Files contained in our single input
    var fileList = this.input[0].files;
    for (var i = 0; i < fileList.length; i++) {
      this.add(fileList[i]);
    }
  },
  handleItemClick: function handleItemClick(evt) {
    var $target = $(evt.currentTarget),
      $item = $target.parents('.fh-item').eq(0),
      file = $item.data('fh.file');
    this.preview.show(file);
  },
  initPreview: function() {
    var $cont = $('<div>', {
        class: 'fh-preview'
      }),
      img = new Image();

    return {
      container: $cont.append(img),
      update: function updatePreview(url) {},
      show: function show(file) {
        if (!(file instanceof Blob)) {
          console.warn('Not a Blob', file);
          throw new TypeError('Argument 1 must be Blob or a File');
        }
        if (this.current !== file) {
          this.current = file;
          img.src = URL.createObjectURL(file);
        }
        $cont.show();
      },
      hide: function hide() {
        img.src = '#';
        $cont.hide();
      }

    };
  }

});


var fileHandler = new FileHandler({
  input: {
    accept: 'image/*'
  }
});
$('body').append(
  fileHandler.addButton,
  $('<button>', {
    text: 'send to server'
  })
  .on('click', sendToServer),
  fileHandler.items_container,
  fileHandler.preview.container,
);
.fh-item {
  border: 1px solid;
  display: inline-block;
  min-width: 130px;
  min-height: 130px;
  vertical-align: middle;
}

.fh-file_name {
  display: inline-block;
  width: 100px;
  overflow: hidden;
  text-overflow: ellipsis;
  margin: 2px 4px;
  vertical-align: top;
}

.fh-remove {
  box-shadow: none;
  border: none;
  float: right;
  cursor: pointer;
}

.fh-remove:hover {
  color: #CC0000;
}

.fh-thumb {
  text-align: center;
  width: 100%;
  height: 100px;
}

.fh-thumb>img {
  max-width: 100px;
  max-height: 100px;
  margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
© www.soinside.com 2019 - 2024. All rights reserved.