Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support of APNG #123

Closed
wants to merge 1 commit into from

Conversation

hoshi-sano
Copy link

What is this?

I added APNG support to ChunkyPNG.
You can decord/encord the Animated PNG file.
Also you can R/W access to the frame images's pixels like you do for the ChunkyPNG::Canvas.
Low level access to APNG-specific chunks is also possible.

refs:

What did I do?

I made it possible for ChunkyPNG::Chunk module to parse acTL/fcTL/fdAT chunk types.
And I added the following three classes.

  • ChunkyPNG::Animation - class to represent APNG images
  • ChunkyPNG::Frame - class to represent each frames that construct the animation
  • ChunkyPNG::AnimationDatastream - represents the internal structure of an APNG

Usage

I will show some samples.
Since APNG images are included, please view the following samples with APNG supported browsers (Safari/Firefox).

Read APNG file

input:
apng-sample

require 'chunky_png'

animation = ChunkyPNG::Animation.from_file('apng-sample.png')
puts "width: #{animation.width}px"         #=> width: 200px
puts "height: #{animation.height}px"       #=> height: 200px
puts "num_frames: #{animation.num_frames}" #=> num_frames: 8
puts "num_plays: #{animation.num_plays}"   #=> num_plays: 0 (infinite loop)

Modify and Export

input:
apng-sample

output:
out_1

require 'chunky_png'

animation = ChunkyPNG::Animation.from_file('apng-sample.png')
ads = animation.to_datastream
ads.each_chunk do |c|
  next unless c.is_a?(ChunkyPNG::Chunk::FrameControl)
  c.delay_den = c.delay_den / 2
end
ads.save('out_1.png')

Create animation from multiple images

input:
frame-images-1

output:
out_2

require 'chunky_png'

frame_attrs = { delay_num: 1, delay_den: 10 }
animation = nil
(0..7).each do |i|
  name = '%03d' % i
  frame = ChunkyPNG::Frame.from_file("{name}.png", frame_attrs)
  if i == 0
    animation = ChunkyPNG::Animation.from_frame(frame)
  else
    animation.frames << frame
  end
end
animation.save('out_2.png')

Create animation from multiple images 2

In addition to above, prepare a default image for users of unsupported browsers.

input:
above 000-007.png and
error

output:
out_3
create-animation-with-images-2
(left: supported browser, right: unsupported browser)

require 'chunky_png'

frame_attrs = { delay_num: 1, delay_den: 10 }
animation = ChunkyPNG::Animation.from_file('error.png')
(0..7).each do |i|
  name = '%03d' % i
  frame = ChunkyPNG::Frame.from_file("#{name}.png", frame_attrs)
  animation.frames << frame
end
animation.save('out_3.png')

Create animation from single image

input:
face

output:
out_4

require 'chunky_png'

radius = 10
ref_x = 40
ref_y = 40
animation = ChunkyPNG::Animation.new(200, 200, ChunkyPNG::Color::WHITE)
base_attrs = { delay_num: 1, delay_den: 10, dispose_op: 2, blend_op: 1 }
0.step(359, 20) do |degrees|
  radian = degrees * Math::PI / 180
  x_offset = ref_x + (radius * Math.cos(radian)).round
  y_offset = ref_y + (radius * Math.sin(radian)).round
  each_frame_attrs = base_attrs.merge(x_offset: x_offset, y_offset: y_offset)
  frame = ChunkyPNG::Frame.from_file('face.png', each_frame_attrs)
  animation.frames << frame
end
animation.save('out_4.png')

Who use this?

Uhmm... it's difficult.
However, as far as I know the following events have occured recently.

  1. Added APNG support to Chromium https://codereview.chromium.org/2618633004/
  2. Message app LINE allows creators to make animation stickers in APNG format since Jun 2016.
  3. CLIP STUDIO PAINT supported exporting animation as APNG since ver1.6.3 (released Oct 2016).

2 and 3 may not affect other than Japan.
LINE's market share is biased toward Japan (https://www.similarweb.com/blog/worldwide-messaging-apps , https://techcrunch.com/2012/12/04/global-messaging-market/).
CLIP STUDIO PAINT is made in Japan, many of the users will be Japanese.

Nevertheless, I expect that APNG will become widespread in the near future.

Finaly

I hope it will be the basis for discussion.

However, I know that you want to keep this library small.
So, even if this Pull-Request is rejected I will think your decision is reasonable and I will respect it.

Thank you.

@wvanbergen
Copy link
Owner

This is really cool! Hoping to do a full review of this - I have a bunch of things on my plate right now, but hopefully before the end of the week.

@daniel-illi
Copy link

What's the status of this pull request?
We could use this feature.

@kaspergrubbe
Copy link

This could be cool to have merged.

@wvanbergen
Copy link
Owner

Hello, thanks again for the contribution. I want to apologize for the long delay on this PR.

I have decide to close this PR without merging. The reason for this is that I am maintaining this gem in my limited spare time, and have to be careful about how much support load I take on.

For this reason, this gem is in "maintenance" mode:

  • I am considering this gem feature complete. As a result I will be very hesitant to accept new functionality and API surface to this gem. Specifically in this case: I know nothing myself about APNG, which will make it painful for me to support this after it is merged.
  • I am still; happy to work on (or accept contributions for) things like bug fixes, performance improvements, code cleanup, security issues, etc.

For new functionality, I would suggest making them available as separate "plugin" gems (e.g. chunky_png-apng) in this case. If anything in the gem needs to be refactored to support this kind of extensibility, I am happy to accept PRs for that.

I will be updating the README of this project to include this message.

@wvanbergen wvanbergen closed this Aug 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants