Я пытаюсь отобразить строку в кодировке base64 в формате jpeg.На сервере (C #) я просто возвращаю закодированную строку (просто жесткое кодирование для целей тестирования, игнорируя переданный параметр):
[HttpGet("[action]")]
public string GetImage(string imageInfo)
{
// get the path to the image, using the passed imageInfo
var imgPath = @"C:\SmallFiles\TestLogo.jpg";
// return base64 string
byte[] imageArray = System.IO.File.ReadAllBytes(imgPath);
string base64ImageRepresentation = Convert.ToBase64String(imageArray);
return base64ImageRepresentation;
}
Когда я беру эту строку (base64ImageRepresentation) и вставляю ее впреобразователь text-jpeg (https://onlinejpgtools.com/convert-base64-to-jpg), изображение отображается правильно, и закодированная строка начинается с этого: "/ 9j / 4". И я могу убедиться, что это на самом деле возвращается в браузер, используяВкладка Chrome Network.
Теперь, вот мой компонент Angular 5:
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
})
export class HomeComponent {
baseUrl: string;
sanitizedImageSrc: SafeResourceUrl;
constructor(private route: ActivatedRoute, private _http: HttpClient, @Inject('BASE_URL') baseUrl: string, private _sanitizer: DomSanitizer) {
this.baseUrl = baseUrl;
}
ngOnInit() {
// if image information is being passed to the page, get the parameter information
let imageLookupInfo = this.route.snapshot.queryParamMap.get('imgInfo');
if (imageLookupInfo)
this.getImage(imageLookupInfo).subscribe(
data => {
this.createImageFromBlob(data);
},
error => console.error(error));
}
createImageFromBlob(image: Blob) {
let reader = new FileReader();
reader.addEventListener("load", () => {
let result = reader.result;
let imgString = result.toString().replace('text/plain', 'image/jpeg');
this.sanitizedImageSrc = this._sanitizer.bypassSecurityTrustResourceUrl(imgString);
}, false);
if (image) {
reader.readAsDataURL(image);
}
}
getImage(imageLookupInfo: string): Observable<Blob> {
return this._http.get(this.baseUrl + 'api/SampleData/GetImage?imageInfo=' + imageLookupInfo, { responseType: "blob" });
}
}
И мой HTML:
<div class='row'>
<div class='col-lg-10 col-md-10 col-sm-10 col-xs-10'>
<h1>Test Image Display</h1>
<div *ngIf="sanitizedImageSrc">
<img [src]="sanitizedImageSrc" width="100" height="50">
</div>
</div>
</div>
В методе createImageFromBlob я обнаружил, чтоimage Blob всегда имеет тип «text / plain»: Blob(26544) {size: 26544, type: "text/plain"}
Свойство type доступно только для чтения, поэтому я не могу его изменить. Вместо этого я жду, пока BLOB-объект преобразуется в строку черезМетод FileReader «readAsDataURL», а затем я делаю замену на «image / jpeg» (пожалуйста, дайте мне знать, если есть лучший способ), который дает мне imgString, которая начинается так:
"data:image/jpeg;base64,LzlqLzRBQVFTa1pKUmdBQkFRRUF"
Обратите внимание, как данные теперь начинаются с "Lzlq "а не" / 9j / 4 ".С чего бы это ???И когда я копирую полный текст закодированных данных и вставляю его в тот же конвертер текста в JPEG (https://onlinejpgtools.com/convert-base64-to-jpg),, я вообще не вижу изображения, которое именно то, что показано на моей веб-странице - вообще ничегоНет ошибок, просто нет изображения.
Что я делаю не так? Что здесь происходит? Кажется, это должно быть так просто. У кого-нибудь есть рабочий пример того, как это сделать?
Любая помощь будет наиболее ценной.
Спасибо, - Джон
ОБНОВЛЕНИЕ : я сделал эту работу со строкой в кодировке base64 следующим образом. Это делает не ответьте на вопрос, почему подход Blob не сработал для меня, и я все еще хотел бы знать, но этот подход сработал для меня, если кто-то сочтет его полезным.
1) Измените сторону сервера так, чтобы она возвращала объект ImageInfo, определенный следующим образом:
public class ImageInfo
{
public string FileExtension { get; set; }
public string Base64EncodedContent { get; set; }
}
Таким образом, код на стороне сервера теперь выглядит следующим образом:
[HttpGet("[action]")]
public ImageInfo GetImageInfo(string imageInfo)
{
// get the path to the image, using the passed imageInfo
var imgPath = @"C:\SmallFiles\TestLogo.jpg";
// get image as base64 string
byte[] imageArray = System.IO.File.ReadAllBytes(imgPath);
string base64ImageRepresentation = Convert.ToBase64String(imageArray);
var info = new ImageInfo();
info.FileExtension = "jpeg";
info.Base64EncodedContent = base64ImageRepresentation;
return info;
}
Затем угловой компонент изменяется напросто используйте два свойства возвращаемого объекта, определитеned в этом интерфейсе:
export interface ImageInfo {
fileExtension: string;
base64EncodedContent: string;
}
И компонент выглядит следующим образом (просто подтверждение концепции кода, а не реализация, достойная производства):
import { Component, Inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { ImageInfo } from '../interfaces/imageInfo';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
})
export class HomeComponent {
baseUrl: string;
sanitizedImageSrc: SafeResourceUrl;
constructor(private route: ActivatedRoute, private _http: HttpClient, @Inject('BASE_URL') baseUrl: string, private _sanitizer: DomSanitizer) {
this.baseUrl = baseUrl;
}
ngOnInit() {
// if image information is being passed to the page, get the parameter information
let imageLookupInfo = this.route.snapshot.queryParamMap.get('imgInfo');
if (imageLookupInfo)
this.getImageInfo(imageLookupInfo)
.subscribe(
imageInfo => {
this.sanitizedImageSrc = this._sanitizer.bypassSecurityTrustResourceUrl('data:image/' + imageInfo.fileExtension + ';base64,' + imageInfo.base64EncodedContent);
},
error => console.error(error)
);
}
getImageInfo(imageLookupInfo: string): Observable<ImageInfo> {
return this._http.get<ImageInfo>(this.baseUrl + 'api/SampleData/GetImageInfo?imageInfo=' + imageLookupInfo);
}
}