diff --git a/reference/bitmap assets/LICENSE.txt b/reference/bitmap assets/LICENSE.txt index 64b665f..6e26645 100644 --- a/reference/bitmap assets/LICENSE.txt +++ b/reference/bitmap assets/LICENSE.txt @@ -13,3 +13,23 @@ I, Jonathan Zander, CC BY-SA 3.0 , via Wikimedia Commons + +https://commons.wikimedia.org/wiki/File:Nycticorax_nycticorax12.jpg +This file is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported, 2.5 Generic, 2.0 Generic and 1.0 Generic license. +Calibas + +https://commons.wikimedia.org/wiki/File:Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg +This work is in the public domain in its country of origin and other countries and areas where the copyright term is the author's life plus 100 years or fewer. +Vincent van Gogh +Google Arts & Culture + +https://commons.wikimedia.org/wiki/File:Tulipa_suaveolens_floriade_to_Canberra.jpg +This file is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license. +John O'Neill + +https://commons.wikimedia.org/wiki/File:International_hot_air_balloon_festival_in_leon_guanajuato_mexico_2012.jpg +This file is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license. +Tomascastelazo +https://commons.wikimedia.org/wiki/File:Hot-air_balloon_in_Tambov_-_02.jpg +This file is licensed under the Creative Commons Attribution-Share Alike 4.0 International license. +Alexander Novikov diff --git a/src/bitmap/LICENSES.toml b/src/bitmap/LICENSES.toml index 6c017c8..824c498 100644 --- a/src/bitmap/LICENSES.toml +++ b/src/bitmap/LICENSES.toml @@ -1,5 +1,23 @@ [[licenses]] file = 'Niinsaare_järv.jpg' license = "CC-BY-SA-3.0" -authors = ["Ivar Leidus", "Wikimedia Commons"] +authors = ["Ivar Leidus"] source = 'https://commons.wikimedia.org/wiki/File:Niinsaare_j%C3%A4rv.jpg' + +[[licenses]] +file = 'Tulipa_suaveolens_floriade_to_Canberra.jpg' +license = "CC-BY-SA-3.0" +authors = ["John O'Neill"] +source = 'https://commons.wikimedia.org/wiki/File:Tulipa_suaveolens_floriade_to_Canberra.jpg' + +[[licenses]] +file = 'Hot-air_balloon_in_Tambov_-_02.jpg' +license = "CC-BY-SA-4.0" +authors = ["Alexander Novikov"] +source = 'https://commons.wikimedia.org/wiki/File:Hot-air_balloon_in_Tambov_-_02.jpg' + +[[licenses]] +file = 'Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg' +license = "CC0-1.0" # Public Domain actually. +authors = ["Vincent van Gogh", "Google Arts & Culture"] +source = 'https://commons.wikimedia.org/wiki/File:Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg' diff --git a/src/bitmap/Tulipa_suaveolens_floriade_to_Canberra-mask.png~ b/src/bitmap/Tulipa_suaveolens_floriade_to_Canberra-mask.png~ new file mode 100644 index 0000000..4496f79 Binary files /dev/null and b/src/bitmap/Tulipa_suaveolens_floriade_to_Canberra-mask.png~ differ diff --git a/tool/src/aurora_iconset_builder/assemblicon/geometry.py b/tool/src/aurora_iconset_builder/assemblicon/geometry.py index ee4011f..b7966e5 100644 --- a/tool/src/aurora_iconset_builder/assemblicon/geometry.py +++ b/tool/src/aurora_iconset_builder/assemblicon/geometry.py @@ -78,7 +78,7 @@ class Rectangle: width: int, height: int, top: int, right: int, bottom: int, left: int ) -> "Rectangle": """ - TODO + Create the rectangle with the size of this region's parent, and the margin between this region and its parent. :param width: The width of parent. :param height: The height of parent. @@ -94,7 +94,7 @@ class Rectangle: pos: Point, top: int, right: int, bottom: int, left: int ) -> "Rectangle": """ - TODO + Create the rectangle with the central point in this region's parent, and the padding between this point and region's border. :param x: The X factor of reference point. :param y: The Y factor of reference point. @@ -103,7 +103,9 @@ class Rectangle: :param bottom: The distance from reference point to this rectangle's bottom border. :param left: The distance from reference point to this rectangle's left border. """ - return Rectangle(Point(pos.x - left, pos.y - top), Point(pos.x + right, pos.y + bottom)) + return Rectangle( + Point(pos.x - left, pos.y - top), Point(pos.x + right, pos.y + bottom) + ) @property def width(self) -> int: diff --git a/tool/src/aurora_iconset_builder/nostd_icons/mimetype_icons.py b/tool/src/aurora_iconset_builder/nostd_icons/mimetype_icons.py index 2101cc9..a0e2c5c 100644 --- a/tool/src/aurora_iconset_builder/nostd_icons/mimetype_icons.py +++ b/tool/src/aurora_iconset_builder/nostd_icons/mimetype_icons.py @@ -1,75 +1,8 @@ -import PIL.Image -import PIL.ImageEnhance from ..types import AuroraContext, AuroraEnvironment from ..assemblicon.highlevel.utils import FdContext, WinCategory, MacCategory -from ..assemblicon.highlevel.source import SvgSource, BitmapSource, TempArtSource +from ..assemblicon.highlevel.source import SvgSource, TempArtSource from ..assemblicon.highlevel.sink import TempArtSink, FdArtSink, WinArtSink, MacArtSink -from ..assemblicon.geometry import Rectangle, Point -from ..assemblicon.lowlevel.artproc import ( - aspect_ratio_scale_and_crop, - VerticalAnchor, - HorizontalAnchor, -) def register(ctx: AuroraContext) -> None: - ctx.register( - "nostd/mimetype/image-jpeg", - ( - TempArtSource("component", "image-base.png"), - BitmapSource("bitmap", "Niinsaare_järv.jpg"), - TempArtSink("image-jpeg.png"), - FdArtSink(FdContext.MimeTypes, "image-jpeg"), - WinArtSink(WinCategory.Extension, "jpg"), - MacArtSink(MacCategory.Extension, "jpg"), - ), - build_image_jpeg_icon, - ) - - -IMAGE_INNER_RECT = Rectangle(Point(20 * 4, 52 * 4), Point(236 * 4, 204 * 4)) - -def build_image_jpeg_icon( - env: AuroraEnvironment, - base_src: TempArtSource, - bitmap_src: BitmapSource, - temp_sink: TempArtSink, - fd_sink: FdArtSink, - win_sink: WinArtSink, - mac_sink: MacArtSink, -) -> None: - jpg_image = base_src.pull(env) - - jpg_image_inner = bitmap_src.pull(env) - with jpg_image_inner: - # crop the area which is interested by ourselves - interest_area = Rectangle.from_pos_size_rect(Point(2700, 0), 5016, 3888) - crop_jpg_image_inner = jpg_image_inner.crop(interest_area.to_tuple()) - # do a flip - flip_jpg_image_inner = crop_jpg_image_inner.transpose( - PIL.Image.Transpose.FLIP_LEFT_RIGHT - ) - # enhance its saturation - enhancer = PIL.ImageEnhance.Color(flip_jpg_image_inner) - saturated_jpg_image_inner = enhancer.enhance(1.4) - - # fit to inner rect - bestfit_jpg_image_inner = aspect_ratio_scale_and_crop( - saturated_jpg_image_inner, - IMAGE_INNER_RECT.width, - IMAGE_INNER_RECT.height, - PIL.Image.Resampling.NEAREST, - HorizontalAnchor.Center, - VerticalAnchor.Center, - ) - # paste into inner rect - jpg_image.paste(bestfit_jpg_image_inner, IMAGE_INNER_RECT.to_tuple()) - - # build artifacts - # save as temporary for future use - temp_sink.push(env, jpg_image) - # save for FD - fd_sink.push(env, jpg_image) - # save for windows and mac - win_sink.push(env, jpg_image) - mac_sink.push(env, jpg_image) + pass diff --git a/tool/src/aurora_iconset_builder/std_icons/components.py b/tool/src/aurora_iconset_builder/std_icons/components.py index cec9581..6f75418 100644 --- a/tool/src/aurora_iconset_builder/std_icons/components.py +++ b/tool/src/aurora_iconset_builder/std_icons/components.py @@ -18,14 +18,6 @@ def register(ctx: AuroraContext) -> None: ), build_generic_background, ) - ctx.register( - "component/image-base", - ( - SvgSource("component", "image-base.svg"), - TempArtSink("component", "image-base.png"), - ), - build_image_base_icon, - ) ctx.register( "component/triangles", ( @@ -67,12 +59,6 @@ def build_generic_background( src.pull_to_temp(env, sink) -def build_image_base_icon( - env: AuroraEnvironment, src: SvgSource, sink: TempArtSink -) -> None: - src.pull_to_temp(env, sink) - - def build_triangle_icons( env: AuroraEnvironment, tri_src: SvgSource, diff --git a/tool/src/aurora_iconset_builder/std_icons/mimetype_icons.py b/tool/src/aurora_iconset_builder/std_icons/mimetype_icons.py index 62c3417..7262c39 100644 --- a/tool/src/aurora_iconset_builder/std_icons/mimetype_icons.py +++ b/tool/src/aurora_iconset_builder/std_icons/mimetype_icons.py @@ -1,10 +1,32 @@ +import PIL.Image +import PIL.ImageEnhance from ..types import AuroraContext, AuroraEnvironment -from ..assemblicon.highlevel.utils import FdContext -from ..assemblicon.highlevel.source import FdArtSource -from ..assemblicon.highlevel.sink import FdArtSink +from ..assemblicon.highlevel.utils import FdContext, WinCategory, MacCategory +from ..assemblicon.highlevel.source import ( + SvgSource, + BitmapSource, + TempArtSource, + FdArtSource, +) +from ..assemblicon.highlevel.sink import TempArtSink, FdArtSink, WinArtSink, MacArtSink +from ..assemblicon.geometry import Rectangle, Point +from ..assemblicon.lowlevel.artio import new_artifact +from ..assemblicon.lowlevel.artproc import ( + aspect_ratio_scale_and_crop, + VerticalAnchor, + HorizontalAnchor, +) def register(ctx: AuroraContext) -> None: + ctx.register( + "component/image-base", + ( + SvgSource("component", "image-base.svg"), + TempArtSink("component", "image-base.png"), + ), + build_image_base_icon, + ) ctx.register( "std/mimetype/image-x-generic", ( @@ -13,6 +35,59 @@ def register(ctx: AuroraContext) -> None: ), build_image_x_generic, ) + ctx.register( + "std/mimetype/image-jpeg", + ( + TempArtSource("component", "image-base.png"), + BitmapSource("bitmap", "Niinsaare_järv.jpg"), + TempArtSink("image-jpeg.png"), + FdArtSink(FdContext.MimeTypes, "image-jpeg"), + WinArtSink(WinCategory.Extension, "jpg"), + MacArtSink(MacCategory.Extension, "jpg"), + ), + build_image_jpeg_icon, + ) + ctx.register( + "std/mimetype/image-png", + ( + TempArtSource("component", "image-base.png"), + BitmapSource("bitmap", "Tulipa_suaveolens_floriade_to_Canberra.jpg"), + BitmapSource("bitmap", "Tulipa_suaveolens_floriade_to_Canberra-mask.png"), + SvgSource("image-png-checkerboard.svg"), + FdArtSink(FdContext.MimeTypes, "image-png"), + WinArtSink(WinCategory.Extension, "png"), + MacArtSink(MacCategory.Extension, "png"), + ), + build_image_png_icon, + ) + ctx.register( + "std/mimetype/image-bmp", + ( + TempArtSource("component", "image-base.png"), + BitmapSource("bitmap", "Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg"), + FdArtSink(FdContext.MimeTypes, "image-bmp"), + WinArtSink(WinCategory.Extension, "bmp"), + MacArtSink(MacCategory.Extension, "bmp"), + ), + build_image_bmp_icon, + ) + ctx.register( + "std/mimetype/image-gif", + ( + TempArtSource("component", "image-base.png"), + BitmapSource("bitmap", "Hot-air_balloon_in_Tambov_-_02.jpg"), + FdArtSink(FdContext.MimeTypes, "image-gif"), + WinArtSink(WinCategory.Extension, "gif"), + MacArtSink(MacCategory.Extension, "gif"), + ), + build_image_gif_icon, + ) + + +def build_image_base_icon( + env: AuroraEnvironment, src: SvgSource, sink: TempArtSink +) -> None: + src.pull_to_temp(env, sink) def build_image_x_generic( @@ -20,3 +95,176 @@ def build_image_x_generic( ) -> None: # use image/jpeg as the default image icon src.link_to(env, sink) + + +IMAGE_INNER_RECT = Rectangle(Point(20 * 4, 52 * 4), Point(236 * 4, 204 * 4)) +"""The valid region of image-base for putting inner image.""" + + +def build_image_jpeg_icon( + env: AuroraEnvironment, + base_src: TempArtSource, + bitmap_src: BitmapSource, + temp_sink: TempArtSink, + fd_sink: FdArtSink, + win_sink: WinArtSink, + mac_sink: MacArtSink, +) -> None: + jpg_image = base_src.pull(env) + + jpg_image_inner = bitmap_src.pull(env) + with jpg_image_inner: + # crop the area which is interested by ourselves + interest_area = Rectangle.from_pos_size_rect(Point(2700, 0), 5016, 3888) + crop_jpg_image_inner = jpg_image_inner.crop(interest_area.to_tuple()) + # do a flip + flip_jpg_image_inner = crop_jpg_image_inner.transpose( + PIL.Image.Transpose.FLIP_LEFT_RIGHT + ) + # enhance its saturation + enhancer = PIL.ImageEnhance.Color(flip_jpg_image_inner) + saturated_jpg_image_inner = enhancer.enhance(1.4) + + # fit to inner rect + bestfit_jpg_image_inner = aspect_ratio_scale_and_crop( + saturated_jpg_image_inner, + IMAGE_INNER_RECT.width, + IMAGE_INNER_RECT.height, + PIL.Image.Resampling.NEAREST, + HorizontalAnchor.Center, + VerticalAnchor.Center, + ) + # paste into inner rect + jpg_image.paste(bestfit_jpg_image_inner, IMAGE_INNER_RECT.to_tuple()) + + # build artifacts + # save as temporary for future use + temp_sink.push(env, jpg_image) + # save for FD + fd_sink.push(env, jpg_image) + # save for windows and mac + win_sink.push(env, jpg_image) + mac_sink.push(env, jpg_image) + + +def build_image_png_icon( + env: AuroraEnvironment, + base_src: TempArtSource, + bitmap_src: BitmapSource, + bitmap_mask_src: BitmapSource, + checkerboard_src: SvgSource, + fd_sink: FdArtSink, + win_sink: WinArtSink, + mac_sink: MacArtSink, +) -> None: + png_image = base_src.pull(env) + + bitmap = bitmap_src.pull(env) + bitmap_mask = bitmap_mask_src.pull(env) + checkerboard = checkerboard_src.pull(env) + + with bitmap, bitmap_mask, checkerboard: + # mask bitmap first + # force mask as grayscale format to apply black-white mask instead of alpha channel mask + bitmap_masked = new_artifact(bitmap.size) + bitmap_masked.paste(bitmap, (0, 0), bitmap_mask.convert("L")) + + # we use the whole image as the inner, + # so we directly fit it to inner. + bestfit_bitmap = aspect_ratio_scale_and_crop( + bitmap_masked, + IMAGE_INNER_RECT.width, + IMAGE_INNER_RECT.height, + PIL.Image.Resampling.NEAREST, + HorizontalAnchor.Center, + VerticalAnchor.Top, + ) + # TODO: When bestfit this checkerboard, the border of this checkerboard aer lost. + # We may need resolve this in future but currently it is so subtle to notice. + bestfit_checkerboard = aspect_ratio_scale_and_crop( + checkerboard, + IMAGE_INNER_RECT.width, + IMAGE_INNER_RECT.height, + PIL.Image.Resampling.NEAREST, + HorizontalAnchor.Center, + VerticalAnchor.Center, + ) + + # composite them together + png_image.alpha_composite( + bestfit_checkerboard, IMAGE_INNER_RECT.pos1.to_tuple() + ) + png_image.alpha_composite(bestfit_bitmap, IMAGE_INNER_RECT.pos1.to_tuple()) + + # build artifacts + # save for FD + fd_sink.push(env, png_image) + # save for windows and mac + win_sink.push(env, png_image) + mac_sink.push(env, png_image) + + +def build_image_bmp_icon( + env: AuroraEnvironment, + base_src: TempArtSource, + bitmap_src: BitmapSource, + fd_sink: FdArtSink, + win_sink: WinArtSink, + mac_sink: MacArtSink, +) -> None: + bmp_image = base_src.pull(env) + + bmp_image_inner = bitmap_src.pull(env) + with bmp_image_inner: + # we use the whole image as the inner, + # so we directly fit it to inner. + bestfit_inner = aspect_ratio_scale_and_crop( + bmp_image_inner, + IMAGE_INNER_RECT.width, + IMAGE_INNER_RECT.height, + PIL.Image.Resampling.NEAREST, + HorizontalAnchor.Center, + VerticalAnchor.Center, + ) + # paste into inner rect + bmp_image.paste(bestfit_inner, IMAGE_INNER_RECT.to_tuple()) + + # build artifacts + # save for FD + fd_sink.push(env, bmp_image) + # save for windows and mac + win_sink.push(env, bmp_image) + mac_sink.push(env, bmp_image) + + +def build_image_gif_icon( + env: AuroraEnvironment, + base_src: TempArtSource, + bitmap_src: BitmapSource, + fd_sink: FdArtSink, + win_sink: WinArtSink, + mac_sink: MacArtSink, +) -> None: + gif_image = base_src.pull(env) + + gif_image_inner = bitmap_src.pull(env) + with gif_image_inner: + # we use the whole image as the inner, + # so we directly fit it to inner. + bestfit_inner = aspect_ratio_scale_and_crop( + gif_image_inner, + IMAGE_INNER_RECT.width, + IMAGE_INNER_RECT.height, + PIL.Image.Resampling.NEAREST, + HorizontalAnchor.Center, + VerticalAnchor.Center, + ) + # paste into inner rect + gif_image.paste(bestfit_inner, IMAGE_INNER_RECT.to_tuple()) + + # build artifacts + # save for FD + fd_sink.push(env, gif_image) + # save for windows and mac + win_sink.push(env, gif_image) + mac_sink.push(env, gif_image) diff --git a/tool/src/aurora_iconset_builder/std_icons/status_icons.py b/tool/src/aurora_iconset_builder/std_icons/status_icons.py index aa569e8..7d69552 100644 --- a/tool/src/aurora_iconset_builder/std_icons/status_icons.py +++ b/tool/src/aurora_iconset_builder/std_icons/status_icons.py @@ -64,6 +64,8 @@ def build_dialog_warning_icon( def build_dialog_error_icon( env: AuroraEnvironment, src: SvgSource, temp_sink: TempArtSink, fd_sink: FdArtSink ) -> None: + # TODO: update this icon from rectangle to circle + # save dialog icon with FreeDesktop icon and temp icon for reuse. src.pull_to_temp(env, temp_sink) with temp_sink.repull(env) as art: