Skip to content

Commit

Permalink
Cherry pick 34ce14d a7ccb34 (#763)
Browse files Browse the repository at this point in the history
* return default asset metadata if there isn't label data (#669)

* return default asset metadata if there isn't label data


* return default asset metadata if there isn't label data

Co-authored-by: Starain <v-stache@microsoft.com>
Co-authored-by: Alex Chen <68627897+yongbing-chen@users.noreply.github.com>
Co-authored-by: stew-ro <60453211+stew-ro@users.noreply.github.com>

* avoid pdf was released prematurely in pdfAsset.tsx (#762)

Co-authored-by: starain-pactera <73208113+starain-pactera@users.noreply.github.com>
Co-authored-by: Starain <v-stache@microsoft.com>
Co-authored-by: Alex Chen <68627897+yongbing-chen@users.noreply.github.com>
  • Loading branch information
4 people authored Nov 13, 2020
1 parent 93b7a2d commit 244c23d
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 133 deletions.
148 changes: 34 additions & 114 deletions src/react/components/common/assetPreview/pdfAsset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,11 @@ export interface IPDFAssetState {
*/
export class PDFAsset extends React.Component<IAssetPreviewProps, IPDFAssetState> {
private image: React.RefObject<HTMLImageElement> = React.createRef();
private pdf;
private page;
private renderTask;
private canvas;
private loadingTask;
private unmounted;
private pendingRelease;
private unmounted: boolean;

constructor(props: IAssetPreviewProps) {
super(props);
this.unmounted = false;
this.page = null;
this.pdf = null;
this.renderTask = null;
this.canvas = null;
this.loadingTask = null;
this.pendingRelease = false;
this.state = {
imageUri: "",
};
Expand All @@ -45,7 +33,7 @@ export class PDFAsset extends React.Component<IAssetPreviewProps, IPDFAssetState
}

public componentDidMount() {
if (this.unmounted || this.pendingRelease) {
if (this.unmounted) {
return;
}
if (this.props.asset) {
Expand All @@ -67,99 +55,59 @@ export class PDFAsset extends React.Component<IAssetPreviewProps, IPDFAssetState
src={this.state.imageUri}
alt={this.props.asset.name}
onLoad={this.onLoad}
style={ { display: this.state.imageUri ? "block" : "none" } }
style={{display: this.state.imageUri ? "block" : "none"}}
crossOrigin="anonymous" />
);
}

private loadPdfFile = (url) => {
if (this.unmounted || this.pendingRelease) {
private loadPdfFile = async (url) => {
if (this.unmounted) {
return;
}
this.loadingTask = pdfjsLib.getDocument(url);
this.loadingTask.promise.then((pdf) => {
this.pdf = pdf;
if (this.pendingRelease) {
return
}
if (this.unmounted) {
if (this.pdf) {
this.releaseMemoryUsedByPDF();
}
return;
}
// Fetch the first page
this.loadPdfPage(pdf, 1 /*pageNumber*/);
}, (reason) => {
// PDF loading error
let pdf;
try {
pdf = await pdfjsLib.getDocument(url).promise;
await this.loadPdfPage(pdf, 1);
}
catch (err) {
if (this.props.onError) {
this.props.onError(reason);
this.props.onError(err);
}
}
finally {
if (pdf) {
pdf.destroy();
}
});
}
}

private loadPdfPage = (pdf, pageNumber) => {
if (this.pendingRelease) {
return
}
if (this.unmounted) {
if (this.pdf) {
this.releaseMemoryUsedByPDF();
}
return;
}
pdf.getPage(pageNumber).then((page) => {
this.page = page;
this.page.cleanupAfterRender = true;
private loadPdfPage = async (pdf, pageNumber) => {
const page: any = await pdf.getPage(pageNumber);
if (page) {
page.cleanupAfterRender = true;
const defaultScale = 1;
const viewport = page.getViewport({ scale: defaultScale });
const viewport = page.getViewport({scale: defaultScale});

// Prepare canvas using PDF page dimensions
this.canvas = document.createElement("canvas");
const context = this.canvas.getContext("2d");
this.canvas.height = viewport.height;
this.canvas.width = viewport.width;
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
canvas.height = viewport.height;
canvas.width = viewport.width;

// Render PDF page into canvas context
const renderContext = {
canvasContext: context,
viewport,
};
if (this.pendingRelease || !this.page) {
return
}
if (this.unmounted) {
if (this.page) {
this.releaseMemoryUsedByPDF();
}
return;
}
this.renderTask = page.render(renderContext);
this.renderTask.promise.then(() => {
if (this.pendingRelease) {
return
}
if (this.unmounted || !this.page) {
if (this.page) {
this.releaseMemoryUsedByPDF();
}
return;
}
const thumbnails = resizeCanvas(this.canvas, 240, 240).toDataURL(constants.convertedImageFormat,
constants.convertedThumbnailQuality);
await page.render(renderContext).promise;
const thumbnailsUri = resizeCanvas(canvas, 240, 240).toDataURL(constants.convertedImageFormat,
constants.convertedThumbnailQuality);
if (!this.unmounted) {
this.setState({
imageUri: thumbnails,
}, () => {
if (this.page) {
this.releaseMemoryUsedByPDF();
}
imageUri: thumbnailsUri
});
}).catch((err) => {
this.releaseMemoryUsedByPDF();
});
}).catch((err) => {
this.releaseMemoryUsedByPDF();
});
}
}
}

private onLoad = () => {
Expand All @@ -173,32 +121,4 @@ export class PDFAsset extends React.Component<IAssetPreviewProps, IPDFAssetState
this.props.onDeactivated(this.image.current);
}
}

private async releaseMemoryUsedByPDF() {
if (this.pendingRelease) {
return;
}
this.pendingRelease = true;
try {
if (this.renderTask) {
await this.renderTask?.promise
this.renderTask = null;
}
if (this.loadingTask) {
await this.loadingTask?.promise
this.loadingTask = null;
}
if (this.pdf) {
await this.pdf?.cleanup();
await this.pdf?.destroy();
this.pdf = null;
}
if (this.canvas) {
delete this.canvas;
this.canvas = null;
}
} catch {
// do nothing on rejects
}
}
}
37 changes: 18 additions & 19 deletions src/services/assetService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class AssetService {
private getOcrFromAnalyzeResult(analyzeResult: any) {
return _.get(analyzeResult, "analyzeResult.readResults", []);
}
getAssetPredictMetadata(asset: IAsset, predictResults: any) {
getAssetPredictMetadata(asset: IAsset, predictResults: any): IAssetMetadata {
asset = _.cloneDeep(asset);
const getBoundingBox = (pageIndex, arr: number[]) => {
const ocrForCurrentPage: any = this.getOcrFromAnalyzeResult(predictResults)[pageIndex - 1];
Expand All @@ -85,9 +85,9 @@ export class AssetService {
return result;
};
const getLabelValues = (field: any) => {
return field.elements?.map((path: string):IFormRegion => {
return field.elements?.map((path: string): IFormRegion => {
const pathArr = path.split('/').slice(1);
const word = pathArr.reduce((obj: any, key: string) => obj[key], { ...predictResults.analyzeResult });
const word = pathArr.reduce((obj: any, key: string) => obj[key], {...predictResults.analyzeResult});
return {
page: field.page,
text: word.text || word.state,
Expand All @@ -107,25 +107,24 @@ export class AssetService {
value: getLabelValues(result.fields[key])
}))).flat(2);

const fileName = decodeURIComponent(asset.name).split('/').pop();
const labelData: ILabelData = {
document: fileName,
labels: []
};
const metadata: IAssetMetadata = {
asset: {...asset},
regions: [],
version: appInfo.version,
labelData,
}
if (labels.length > 0) {
const fileName = decodeURIComponent(asset.name).split('/').pop();
const labelData: ILabelData = {
document: fileName,
labelingState: AssetLabelingState.AutoLabeled,
labels
};
const metadata: IAssetMetadata = {
asset: { ...asset, labelingState: AssetLabelingState.AutoLabeled },
regions: [],
version: appInfo.version,
labelData,
};
labelData.labelingState = AssetLabelingState.AutoLabeled;
labelData.labels = labels;
metadata.asset.labelingState = AssetLabelingState.AutoLabeled;
metadata.asset.state = AssetState.Tagged;
return metadata;
}
else {
return null;
}
return metadata;
}
async uploadPredictResultAsOrcResult(asset: IAsset, predictResults: any): Promise<void> {
const ocrData = _.cloneDeep(predictResults);
Expand Down

0 comments on commit 244c23d

Please sign in to comment.