将blob图像恢复为文件

时间:2018-03-03 12:19:47

标签: javascript jquery html blob multipartform-data

我在将图像转换为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);
		}
	});
&#13;
.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;
}
&#13;
<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>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

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

您不必将文件转换为blobURI转换为文件。

只需保留初始文件,将它们保存在良好的文件中即可。数组,从那里管理它们。

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

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

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

&#13;
&#13;
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,
);
&#13;
.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;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;