tblog_duopack 0.0.52 → 0.0.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tblog_duopack.rb +191 -111
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e2bfd10d034977a468d952d911ad19959c7f20de9d25f93cece0693ff7b9e68
4
- data.tar.gz: a736c3c9ea1bc59d2d3bbe389bb85b661a915c5c1a7d4cf5bdeeb3832766ae83
3
+ metadata.gz: 0e127c468134d59313a08b01c510cba01b709a57742decbfc90b92166922a842
4
+ data.tar.gz: 48474e478f91851dbe2d3f77eec084b0b787304e3042a84ab8c0a129ad12fbac
5
5
  SHA512:
6
- metadata.gz: f8513736ced216ea88171f0fd0c5415922dd9bbd0f1bb90d0cd51e53d199c36e5e19f69a5b488e9ee69853c584c8796accfa2f13db1991987e51acf0070364fb
7
- data.tar.gz: b6be12682ea565e3dbdbf7754f9525060ebb828f6078f21673c43917fa2eab88c9f15540557b398c0fc80467e5ea27e8be19c4bd4e3dd70122e4f1cba0d9c254
6
+ metadata.gz: 29860a76946a9a4ba394e9c1154589625dca96ac0c18771cecd6dadca13638a3432af203d01de0f2734165d89dc3df2e4a17f406a0fffb77de6321fbe6a95cca
7
+ data.tar.gz: 013a0938da6ff2565ac2bf2319e7609bd1e3e3c40c8a7371e1bc822b98c5afbc3b606c89cf8733e57d76c09d26e6466bf03423fba6efacd9d6b88b62ae82e7b3
data/lib/tblog_duopack.rb CHANGED
@@ -1756,84 +1756,116 @@ class Wordpress
1756
1756
 
1757
1757
 
1758
1758
 
1759
- def auto_image(keyword = nil)
1760
- keyword ||= @keyword
1761
- puts "키워드: #{keyword}"
1762
-
1763
- client = HTTPClient.new
1764
- client.default_header = {
1765
- 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
1766
- '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
1767
- 'Accept' => 'application/json, text/javascript, */*; q=0.01',
1768
- 'Accept-Language' => 'en-US,en;q=0.9',
1769
- 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
1770
- 'X-Requested-With' => 'XMLHttpRequest'
1771
- }
1759
+ def crop_image_height_under_width(path, min_crop_ratio = 0.625)
1760
+ img = Magick::Image.read(path).first
1761
+ width = img.columns
1762
+ height = img.rows
1772
1763
 
1773
- retry_count = 0
1774
- max_retries = 10
1775
- results = []
1764
+ if height > width
1765
+ min_height = (width * min_crop_ratio).to_i
1766
+ new_height = rand(min_height..width)
1767
+ crop_top = ((height - new_height) / 2.0).round
1776
1768
 
1777
- begin
1778
- page = rand(1..15)
1779
- url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
1780
- puts "Request URL: #{url}"
1781
- res = client.get(url)
1782
-
1783
- unless res.status == 200
1784
- puts "HTTP Error: #{res.status}"
1785
- raise "HTTP Error"
1769
+ cropped = img.crop(0, crop_top, width, new_height, true)
1770
+
1771
+ retries = 0
1772
+ begin
1773
+ cropped.write(path)
1774
+ rescue => e
1775
+ retries += 1
1776
+ puts "이미지 저장 오류 (#{e.message}), 재시도 #{retries}/5"
1777
+ sleep(1)
1778
+ retry if retries < 5
1779
+ raise "이미지 저장 실패: #{e.message}"
1786
1780
  end
1781
+ end
1782
+ end
1787
1783
 
1788
- json = JSON.parse(res.body)
1789
- results = json['results']
1790
- mm = []
1784
+ def auto_image(keyword = nil)
1785
+ # auto_image 내부에서만 crop 호출
1786
+ keyword ||= @keyword
1787
+ puts "키워드: #{keyword}"
1788
+
1789
+ client = HTTPClient.new
1790
+ client.default_header = {
1791
+ 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
1792
+ '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
1793
+ 'Accept' => 'application/json, text/javascript, */*; q=0.01',
1794
+ 'Accept-Language' => 'en-US,en;q=0.9',
1795
+ 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
1796
+ 'X-Requested-With' => 'XMLHttpRequest'
1797
+ }
1798
+
1799
+ retry_count = 0
1800
+ max_retries = 10
1801
+ results = []
1802
+
1803
+ begin
1804
+ page = rand(1..15)
1805
+ url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
1806
+ puts "Request URL: #{url}"
1807
+ res = client.get(url)
1808
+
1809
+ unless res.status == 200
1810
+ puts "HTTP Error: #{res.status}"
1811
+ raise "HTTP Error"
1812
+ end
1791
1813
 
1792
- results.each do |photo|
1793
- full_url = photo.dig('urls', 'full').to_s
1794
- regular_url = photo.dig('urls', 'regular').to_s
1814
+ json = JSON.parse(res.body)
1815
+ results = json['results']
1816
+ mm = []
1795
1817
 
1796
- if full_url.start_with?("https://images.unsplash.com/photo-") &&
1797
- regular_url.include?("1080")
1798
- mm << full_url
1799
- end
1800
- end
1818
+ results.each do |photo|
1819
+ full_url = photo.dig('urls', 'full').to_s
1820
+ regular_url = photo.dig('urls', 'regular').to_s
1801
1821
 
1802
- if mm.empty?
1803
- raise "No matching image"
1804
- end
1822
+ if full_url.start_with?("https://images.unsplash.com/photo-") &&
1823
+ regular_url.include?("1080")
1824
+ mm << full_url
1825
+ end
1826
+ end
1805
1827
 
1806
- selected_url = mm.sample
1807
- Down.download(selected_url, destination: "./image/memory.png")
1808
- puts "이미지 다운로드 완료: #{selected_url}"
1828
+ if mm.empty?
1829
+ raise "No matching image"
1830
+ end
1809
1831
 
1810
- rescue => e
1811
- retry_count += 1
1812
- puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
1813
- sleep(3)
1814
- if retry_count < max_retries
1815
- retry
1816
- else
1817
- puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
1818
-
1819
- if results && !results.empty?
1820
- random_photo = results.sample
1821
- fallback_url = random_photo.dig('urls', 'full')
1822
- if fallback_url
1823
- Down.download(fallback_url, destination: "./image/memory.png")
1824
- puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
1825
- else
1826
- puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
1827
- color_image
1828
- end
1832
+ selected_url = mm.sample
1833
+ destination_path = "./image/memory.png"
1834
+ Down.download(selected_url, destination: destination_path)
1835
+ puts "이미지 다운로드 완료: #{selected_url}"
1836
+
1837
+ # 오직 auto_image에서만 자르기 호출
1838
+ crop_image_height_under_width(destination_path)
1839
+
1840
+ rescue => e
1841
+ retry_count += 1
1842
+ puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
1843
+ sleep(3)
1844
+ if retry_count < max_retries
1845
+ retry
1846
+ else
1847
+ puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
1848
+
1849
+ if results && !results.empty?
1850
+ random_photo = results.sample
1851
+ fallback_url = random_photo.dig('urls', 'full')
1852
+ if fallback_url
1853
+ Down.download(fallback_url, destination: "./image/memory.png")
1854
+ puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
1855
+ crop_image_height_under_width("./image/memory.png")
1829
1856
  else
1830
- puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
1831
- color_image
1832
- end
1857
+ puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
1858
+ color_image
1833
1859
  end
1860
+ else
1861
+ puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
1862
+ color_image
1834
1863
  end
1864
+ end
1865
+ end
1835
1866
  end
1836
1867
 
1868
+
1837
1869
  def color_image
1838
1870
  color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
1839
1871
  image = Magick::Image.new(740, 740) { |k| k.background_color = color.sample }
@@ -1926,56 +1958,103 @@ class Wordpress
1926
1958
  end
1927
1959
 
1928
1960
 
1929
- def image_text(text1, text2)
1961
+ def image_text(text1, text2)
1962
+ begin
1963
+ color = File.open('./color.ini', 'r', encoding: 'utf-8').read.split("\n").map(&:strip).reject(&:empty?)
1964
+ font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
1965
+ font2 = './fonts/' + font_files.sample
1966
+
1967
+ # 랜덤 글자색 선택
1968
+ color2 = color.sample
1969
+
1970
+ # 헬퍼 함수: 색상 문자열 '#RRGGBB' -> [R,G,B] 배열로 변환
1971
+ def hex_to_rgb(hex)
1972
+ hex = hex.delete('#')
1973
+ [hex[0..1], hex[2..3], hex[4..5]].map { |c| c.to_i(16) }
1974
+ end
1975
+
1976
+ # 헬퍼 함수: 두 RGB 색상의 차이 계산 (간단한 유클리드 거리)
1977
+ def color_distance(c1, c2)
1978
+ Math.sqrt(
1979
+ (c1[0] - c2[0])**2 +
1980
+ (c1[1] - c2[1])**2 +
1981
+ (c1[2] - c2[2])**2
1982
+ )
1983
+ end
1984
+
1985
+ # 대비가 충분히 되는 테두리 색상 선택
1986
+ max_attempts = 10
1987
+ stroke_color = nil
1988
+ base_rgb = hex_to_rgb(color2)
1989
+
1990
+ max_attempts.times do
1991
+ candidate = color.sample
1992
+ candidate_rgb = hex_to_rgb(candidate)
1993
+ dist = color_distance(base_rgb, candidate_rgb)
1994
+
1995
+ # 거리(차이) 임계값 100 (0~441 범위) — 필요시 조절 가능
1996
+ if dist > 100
1997
+ stroke_color = candidate
1998
+ break
1999
+ end
2000
+ end
2001
+ stroke_color ||= '#000000' # 만약 충분히 다른 색 없으면 검정색 기본값
2002
+
2003
+ img = Magick::Image.read('./image/memory.png').first
2004
+ draw = Magick::Draw.new
2005
+
2006
+ raw_message = "#{text1}\n#{text2}".strip
2007
+ max_width = img.columns * 0.85
2008
+ max_height = img.rows * 0.6
2009
+
1930
2010
  begin
1931
- color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
1932
- font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
1933
- font2 = './fonts/' + font_files.sample
1934
- color2 = color.sample
1935
-
1936
- img = Magick::Image.read('./image/memory.png').first
1937
- draw = Magick::Draw.new
1938
-
1939
- raw_message = "#{text1}\n#{text2}".strip
1940
- max_width = img.columns * 0.85
1941
- max_height = img.rows * 0.6
1942
-
1943
- begin
1944
- size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
1945
- rescue
1946
- size = 30
1947
- end
1948
-
1949
- wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
1950
-
1951
- if @data['이미지설정']['글자그림자'].checked?
1952
- img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
1953
- draw.gravity = Magick::CenterGravity
1954
- draw.pointsize = adjusted_size
1955
- draw.fill = '#000000'
1956
- draw.font = font2
1957
- end
1958
- end
1959
-
1960
- draw2 = Magick::Draw.new
1961
- img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
1962
- draw2.gravity = Magick::CenterGravity
1963
- draw2.pointsize = adjusted_size
1964
- draw2.fill = color2
1965
- draw2.font = font2
1966
- if @data['이미지설정']['글자테두리'].checked?
1967
- draw2.stroke_width = 2
1968
- draw2.stroke = '#000000'
1969
- end
1970
- end
1971
-
1972
- img.write('./image/memory.png')
2011
+ size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
1973
2012
  rescue
1974
- puts '이미지 폰트 불러오기 오류 재시도...'
1975
- sleep(3)
1976
- retry
2013
+ size = 30
2014
+ end
2015
+
2016
+ wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2017
+
2018
+ if @data['이미지설정']['글자그림자'].checked?
2019
+ img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2020
+ draw.gravity = Magick::CenterGravity
2021
+ draw.pointsize = adjusted_size
2022
+ draw.fill = '#000000'
2023
+ draw.font = font2
2024
+ end
2025
+ end
2026
+
2027
+ if @data['이미지설정']['글자테두리'].checked?
2028
+ draw_stroke = Magick::Draw.new
2029
+ img.annotate(draw_stroke, 0, 0, 0, 0, wrapped_message) do
2030
+ draw_stroke.gravity = Magick::CenterGravity
2031
+ draw_stroke.pointsize = adjusted_size
2032
+ draw_stroke.fill = 'none'
2033
+ draw_stroke.stroke = stroke_color
2034
+ draw_stroke.stroke_width = rand(5..10)
2035
+ draw_stroke.font = font2
2036
+ end
2037
+ end
2038
+
2039
+ draw2 = Magick::Draw.new
2040
+ img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2041
+ draw2.gravity = Magick::CenterGravity
2042
+ draw2.pointsize = adjusted_size
2043
+ draw2.fill = color2
2044
+ draw2.stroke = 'none'
2045
+ draw2.font = font2
1977
2046
  end
2047
+
2048
+ img.write('./image/memory.png')
2049
+
2050
+ rescue => e
2051
+ puts "이미지 폰트 불러오기 오류 재시도... (#{e.message})"
2052
+ sleep(3)
2053
+ retry
1978
2054
  end
2055
+ end
2056
+
2057
+
1979
2058
 
1980
2059
  def border()
1981
2060
  color = File.open('./color.ini', 'r',:encoding => 'utf-8').read().split("\n")
@@ -2002,7 +2081,7 @@ class Wordpress
2002
2081
  else
2003
2082
  auto_image()
2004
2083
  end
2005
-
2084
+
2006
2085
  # '원본'을 포함한 이미지 크기 옵션 추가
2007
2086
  image_size = [480, 740, 650, 550, 480, 'original']
2008
2087
  size = 0
@@ -2026,6 +2105,7 @@ class Wordpress
2026
2105
 
2027
2106
  change_image_size(size) # 크기 변경 함수 호출
2028
2107
 
2108
+
2029
2109
  if @data['이미지설정']['필터사용'].checked?
2030
2110
  image_filter()
2031
2111
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tblog_duopack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.52
4
+ version: 0.0.55
5
5
  platform: ruby
6
6
  authors:
7
7
  - zon
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-05-30 00:00:00.000000000 Z
10
+ date: 2025-06-26 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: File to Clipboard gem
13
13
  email: mymin26@naver.com