以角度 5 上传前的图像预览

Posted

技术标签:

【中文标题】以角度 5 上传前的图像预览【英文标题】:Image preview before upload in angular 5 【发布时间】:2018-11-02 02:45:59 【问题描述】:

我有这段代码在上传之前显示图像预览。但是我正在使用 Angular 5,所以我有一个 .ts 文件而不是 .js 文件。我怎样才能在 Angular 5 中做同样的事情?我还想在所有浏览器中显示图像。

我的 html

<input type='file' onchange="readURL(this);"/>
<img id="blah" src="http://placehold.it/180" />

我的 CSS:

img 
    max-width:180px;


input[type=file] 
    padding: 10px;
    background: #2d2d2d;

我的 javascript

function readURL(input) 
    if (input.files && input.files[0]) 
        var reader = new FileReader();
        reader.onload = function (e) 
            document.getElementById('blah').src=e.target.result
        ;
        reader.readAsDataURL(input.files[0]);
    

【问题讨论】:

只需删除function关键字..应该是它.. 我收到诸如“HTMLElement”类型上不存在属性“src”和“EventTarget”类型上不存在属性“结果”等错误,尽管我的代码相同 【参考方案1】:

.html

更新输入的事件属性和处理程序参数。 你应该对 src 属性使用数据绑定。如果 src 不是 null 或未定义或硬编码的 url ('http://placehold.it/180'),则以下将应用 src

<input type='file' (change)="readURL($event);" />
<img id="blah" [src]="imageSrc || 'http://placehold.it/180'"  />

.ts

在组件 ts 文件(类)中,您应该具有在视图(html)中使用的属性 imageSrc,并且您的函数应该是该类的方法

...
imageSrc: string;
...
constructor(...) ...
...
readURL(event: Event): void 
    if (event.target.files && event.target.files[0]) 
        const file = event.target.files[0];

        const reader = new FileReader();
        reader.onload = e => this.imageSrc = reader.result;

        reader.readAsDataURL(file);
    

【讨论】:

我收到此错误 -> 类型 'EventTarget' 上不存在属性 'result' 。请说明原因。 如果代替硬编码的 url ('placehold.it/180') 我从我存储的图标(如 assets/img/icons/camera-outline.png )中获取占位符图像,相同的代码会保留吗?在这种情况下,我无法看到预览图像。请帮忙。 @MrinaliniPal 如果您使用由 angular-cli 生成的标准 Angular 应用程序,它应该与 assets/.../.../... 等本地路径一起使用。请检查您使用的路径是否正确。 readURL(event) if (event.target.files && event.target.files[0]) const file = event.target.files[0]; const reader = new FileReader(); reader.onload = e => this.imageSrc = reader.result; reader.readAsDataURL(文件); 这里有一个类似技术的例子:talkingdotnet.com/…【参考方案2】:

我正在使用下面的代码来实现图像预览:

onFileChange(event: any) 
this.userFile = event.target.files[0];
this.imageSelected = this.userFile.name;
if (event.target.files && event.target.files[0]) 
  const reader = new FileReader();
  reader.onload = (e: any) => 
    this.imageSrc = e.target.result;
  ;
  reader.readAsDataURL(event.target.files[0]);

效果很好并显示图像预览。我最初遇到的问题是,每次生成图像预览时,我都会在 chrome 开发者工具中收到以下错误:

一切正常,没有其他错误。

如果我点击 null:1,我会被定向到以下内容:

经过一番摆弄和故障排除后,我找到了我在下面的编辑中包含的解决方案。

编辑:想通了。我没有 || 'http://placehold.it/180'" 包含在我的 component.html 上的 [src]=" 中。估计是时间问题。现在排序。没有更多的错误。

【讨论】:

这不是答案 为什么不呢?它对我来说非常好用,没有任何问题。你没看到修改吗? 虽然你的答案不完整令人困惑,但请询问缺少的部分,然后再次回答。我将删除反对票,但我仍然感到困惑 我在 ***.com 的规则中的某处读到,他们更喜欢放置编辑而不是删除可以理解的所有内容,因为如果其他人遇到同样的问题,则有更多的细节和如何解决它。 @chachan 您现在应该可以删除反对票了。谢谢。【参考方案3】:

我知道我迟到了,但我在图像和音频方面都遇到了这个问题。上述解决方案适用于图像,但不适用于音频。我最终通过使用 URL 对象而不是每个人都在使用的 FileReader 对象来完成所有工作。 类似于以下内容

component.ts 文件~

imgSrc = 'assets/path/to/default/image.jpeg'

imgFileSelected(event: any) 
  if (event.target.files && event.target.files[0]) 
    this.imgSrc = URL.createObjectURL(event.target.files[0]);
  

我的component.html看起来像~

<img [src]="imgSrc | sanitizeUrl"> <!-- using a Custom Pipe -->

最后,我创建了一个自定义管道来消除控制台的警告。 我的管道如下~

@Pipe(
  name: 'sanitizerUrl'
)
export class SanitizerUrlPipe implements PipeTransform 

  constructor (
    private sanitize: DomSanitizer
  ) 

  transform(value: string): SafeUrl 
    return this.sanitize.bypassSecurityTrustUrl(value);
  

要了解我是如何将它用于音频标签的,您可以check out this link. 这只是额外的 2 行不言自明的代码。

【讨论】:

【参考方案4】:

请更改喜欢 --> this.url = event.target.result;

readURL(event:any) 
    if (event.target.files && event.target.files[0]) 
        var reader = new FileReader();

        reader.onload = (event:any) = > 
            this.url = event.target.result;
        

        reader.readAsDataURL(event.target.files[0]);
    

【讨论】:

【参考方案5】:

您可能只需将javascript function 更改为typescript,如下所示。

readURL(input) 
    if (input.files && input.files[0]) 
        var reader = new FileReader();

        reader.onload = (e:any) => 
             (<HTMLImageElement>document.getElementById('blah')).src=e.target.result 
             //assuming element with id blah will always be an ImageElement
        ;

        reader.readAsDataURL(input.files[0]);
    

应该是这样的。

更新

您还可以定义一个属性并将其绑定到图像 src 并相应地更改其值,如下所示:

constructor 之前的.ts 文件中,将属性定义为url,并将其默认值设置为http://placehold.it/180

url: string = 'http://placehold.it/180';

您可以在reader.onload 中更新此属性,如下所示:

readURL(event:any) 
  if (event.target.files && event.target.files[0]) 
    var reader = new FileReader();

    reader.onload = (event:any) => 
     this.url = event.target.result;
    

    reader.readAsDataURL(event.target.files[0]);
  

您的html 现在将如下所示:

<input type='file' (change)="readURL(this);" />
<img id="blah" [src]="url"  />

【讨论】:

检查控制台错误.. 你在浏览器控制台中有什么吗? 您声明eventtwice。 onload 中的目标是什么? @GuruprasadRao 多个附件呢?【参考方案6】:

在上传此代码之前预览选择的图像将帮助您,很容易。它只预览图像,如果有其他任何东西,它会给你错误 此代码用于 component.ts

  public imagePath;
 imgURL: any;
 public message: string;
 preview(files) 
 if (files.length === 0)
  return;
 var mimeType = files[0].type;
 if (mimeType.match(/image\/*/) == null) 
  this.message = "Only images are supported.";
  return;
 
 var reader = new FileReader();
 this.imagePath = files;
 reader.readAsDataURL(files[0]); 
 reader.onload = (_event) =>  
 this.imgURL = reader.result; 


以及组件视图中的这些代码行

 <span style="color:red;" *ngIf="message">message</span>
 <input #file type="file" accept='image/*' (change)="preview(file.files)" />
 <img [src]="imgURL"  *ngIf="imgURL">

【讨论】:

【参考方案7】:

使用 @HostListner 怎么样,因为 Angular 没有用于文件输入的内置值访问器。

  @HostListener('change', ['$event.target.files'])
  emitFiles( event: FileList ) 
    const file = event && event.item(0);
    this.onChange(file);
    const reader = new FileReader();
    reader.readAsDataURL(file); // toBase64
    reader.onload = () => 
      this.imageURL = reader.result as string; // base64 Image src
    ;

然后在 HTML 中,你可以使用类似的东西:

  <picture >
    <source media='(min-width:0px)' [srcset]="imageURL">
    <img src=""  [alt]="Your photo">
  </picture>

【讨论】:

【参考方案8】:

对于那些遵循接受的答案并拥有type 'string | ArrayBuffer' is not assignable to type 'string'的人;在影响渲染结果到图像 src 时,您需要添加as string,如下所示

readURL(event: Event): void 
    ...
    reader.onload = e => this.imageSrc = reader.result as string;
    ...

【讨论】:

【参考方案9】:

首先我们在选择文件(imagedisplay.component.html)中通过上传输入图片:

<input #Image type="file" (change)="handleFileInput($event.target.files)"/>
<img  *ngIf="imageUrl" [src]="imageUrl" class="image">
然后我们使用函数来进一步读取和显示这是这样做的(imagedisplay.component.ts):

export class ImageDisplayComponent 
  name = 'Angular';
  fileToUpload: any;
  imageUrl: any;
  handleFileInput(file: FileList) 
    this.fileToUpload = file.item(0);

    //Show image preview
    let reader = new FileReader();
    reader.onload = (event: any) => 
      this.imageUrl = event.target.result;
    
    reader.readAsDataURL(this.fileToUpload);
  

【讨论】:

最好改用imageUrl = URL.createObjectURL(file)

以上是关于以角度 5 上传前的图像预览的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 上传前的JavaScript图片预览

在 Spring MVC 中使用 JavaScript 上传图像以进行预览

如何在上传前调整图像大小并进行预览

如何调整图像的方向以显示正确的图像预览?

图片上传前的预览(PHP)

带预览和删除、Jquery 和 Javascript 的多张图片上传