Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Improved crop file detection in Blender verifier #4176

Merged
merged 3 commits into from
May 15, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from . import types

FILE_TYPES = [
types.Bmp(),
types.Jpeg(),
types.Tga()
]


def get_expected_extension(extension: str) -> str:
"""
Based on the provided file extension string, returns the expected alias
extension that Blender will use for its output. This can be used to avoid
output file names mismatch (e.g. .jpg vs .jpeg extensions). The check is
based on a predefined list of file types.
:param extension: file extension string (with leading dot) to check
against.
:return: expected output file extension (lowercase, with leading dot).
Returns the provided file extension if no alias was found.
"""
lower_extension = extension.lower()

for file_type in FILE_TYPES:
if lower_extension in file_type.extensions:
return file_type.output_format

return lower_extension
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import abc
import typing


class FileType(abc.ABC):
@property
@abc.abstractmethod
def extensions(self) -> typing.AbstractSet[str]:
"""
List of possible extensions (aliases) for the represented file type.
:return: a set of strings, each prefixed with a dot.
"""
pass

@property
@abc.abstractmethod
def output_format(self) -> str:
"""
Returns the file extension expected to be used by Blender for its
output files of the represented file type.
:return: a file extension string, prefixed with a dot.
"""
pass


class Bmp(FileType):
@property
def extensions(self) -> typing.AbstractSet[str]:
return frozenset([
'.bmp',
'.dib'
])

@property
def output_format(self) -> str:
return '.bmp'


class Jpeg(FileType):
@property
def extensions(self) -> typing.AbstractSet[str]:
return frozenset([
'.jpg',
'.jpeg',
'.jpe',
'.jif',
'.jfif',
'.jfi'
])

@property
def output_format(self) -> str:
return '.jpg'


class Tga(FileType):
@property
def extensions(self) -> typing.AbstractSet[str]:
return frozenset([
'.tga',
'.icb',
'.vda',
'.vst'
])

@property
def output_format(self) -> str:
return '.tga'
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import json
import os
from pathlib import Path
from typing import List, Optional
from ..render_tools import blender_render as blender
from .crop_generator import WORK_DIR, OUTPUT_DIR, SubImage, Region, PixelRegion, \
generate_single_random_crop_data, Crop
from .file_extension.matcher import get_expected_extension
from .img_metrics_calculator import calculate_metrics

def get_crop_with_id(id: int, crops: [List[Crop]]) -> Optional[Crop]:
Expand Down Expand Up @@ -77,7 +79,7 @@ def make_verdict( subtask_file_paths, crops, results ):
print("top " + str(top))

for crop, subtask in zip(crop_data['results'], subtask_file_paths):
crop_path = os.path.join(OUTPUT_DIR, crop)
crop_path = get_crop_path(OUTPUT_DIR, crop)
results_path = calculate_metrics(crop_path,
subtask,
left, top,
Expand All @@ -92,6 +94,31 @@ def make_verdict( subtask_file_paths, crops, results ):
json.dump({'verdict': verdict}, f)


def get_crop_path(parent: str, filename: str) -> str:
"""
Attempts to get the path to a crop file. If no file exists under the
provided path, the original file extension is replaced with an expected
one.
:param parent: directory where crops are located.
:param filename: the expected crop file name, based on the file extension
provided in verifier parameters.
:return: path to the requested crop file, possibly with a different file
extension.
:raises FileNotFoundError if no matching crop file could be found.
"""
crop_path = Path(parent, filename)

if crop_path.exists():
return str(crop_path)

expected_extension = get_expected_extension(crop_path.suffix)
expected_path = crop_path.with_suffix(expected_extension)

if expected_path.exists():
return str(expected_path)

raise FileNotFoundError(f'Could not find crop file: {expected_path}')


def verify(subtask_file_paths, subtask_border, scene_file_path, resolution, samples, frames, output_format, basefilename,
crops_count=3, crops_borders=None):
Expand Down
31 changes: 31 additions & 0 deletions tests/apps/blender/verification/test_extension_matcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import typing
import unittest

from apps.blender.resources.images.entrypoints.\
scripts.verifier_tools.file_extension import matcher, types


class TestExtensionMatcher(unittest.TestCase):
def test_bmp_expected_extension(self):
self._assert_expected_extension(types.Bmp().extensions, '.bmp')

def test_jpeg_expected_extension(self):
self._assert_expected_extension(types.Jpeg().extensions, '.jpg')

def test_tga_expected_extension(self):
self._assert_expected_extension(types.Tga().extensions, '.tga')

def test_unknown_extension(self):
extension = '.unkwn'

alias = matcher.get_expected_extension(extension)

self.assertEqual(extension, alias)

def _assert_expected_extension(
self,
aliases: typing.Iterable[str],
expected: str
):
for alias in aliases:
self.assertEqual(matcher.get_expected_extension(alias), expected)