tblog_zon 0.0.52 → 0.0.53
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.
- checksums.yaml +4 -4
- data/lib/tblog_zon.rb +188 -112
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa1ad9cb927ec2743efa587ddda0a06eeb591c0e0f4c976a0d92fe25e1874c22
|
4
|
+
data.tar.gz: a2882c08f99a54cbbe163673f472cf5a2a33820051cfc02b28d2c5f377084b16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24287751283bec290c7ab9984ee8eb64e6002f8c3eaa14db944b79833f8f67f70d1ee2970e61bed97e5cf487ff3e3b9b254b0a7c7aeed08ec85ff694d7a7fcb4
|
7
|
+
data.tar.gz: db253bf93a78bb2a9c4de333cde553e8d5019713e63415ebffab7bc2062640bb0bdada64841a9681e292dca77b7884e66fd417f6f487412d5530c571fb8adba2
|
data/lib/tblog_zon.rb
CHANGED
@@ -1686,84 +1686,112 @@ class Wordpress
|
|
1686
1686
|
|
1687
1687
|
|
1688
1688
|
|
1689
|
-
def
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
client = HTTPClient.new
|
1694
|
-
client.default_header = {
|
1695
|
-
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
|
1696
|
-
'(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
|
1697
|
-
'Accept' => 'application/json, text/javascript, */*; q=0.01',
|
1698
|
-
'Accept-Language' => 'en-US,en;q=0.9',
|
1699
|
-
'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
|
1700
|
-
'X-Requested-With' => 'XMLHttpRequest'
|
1701
|
-
}
|
1689
|
+
def crop_image_height_under_width(path, min_crop_ratio = 0.625)
|
1690
|
+
img = Magick::Image.read(path).first
|
1691
|
+
width = img.columns
|
1692
|
+
height = img.rows
|
1702
1693
|
|
1703
|
-
retry_count = 0
|
1704
|
-
max_retries = 10
|
1705
|
-
results = []
|
1706
1694
|
|
1707
|
-
begin
|
1708
|
-
page = rand(1..15)
|
1709
|
-
url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
|
1710
|
-
puts "Request URL: #{url}"
|
1711
|
-
res = client.get(url)
|
1712
|
-
|
1713
|
-
unless res.status == 200
|
1714
|
-
puts "HTTP Error: #{res.status}"
|
1715
|
-
raise "HTTP Error"
|
1716
|
-
end
|
1717
1695
|
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1696
|
+
if height > width
|
1697
|
+
min_height = (width * min_crop_ratio).to_i
|
1698
|
+
new_height = rand(min_height..width)
|
1699
|
+
crop_top = ((height - new_height) / 2.0).round
|
1721
1700
|
|
1722
|
-
|
1723
|
-
|
1724
|
-
regular_url = photo.dig('urls', 'regular').to_s
|
1701
|
+
cropped = img.crop(0, crop_top, width, new_height, true)
|
1702
|
+
cropped.write(path)
|
1725
1703
|
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1704
|
+
|
1705
|
+
else
|
1706
|
+
|
1707
|
+
end
|
1708
|
+
end
|
1731
1709
|
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1710
|
+
def auto_image(keyword = nil)
|
1711
|
+
# auto_image 내부에서만 crop 호출
|
1712
|
+
keyword ||= @keyword
|
1713
|
+
puts "키워드: #{keyword}"
|
1714
|
+
|
1715
|
+
client = HTTPClient.new
|
1716
|
+
client.default_header = {
|
1717
|
+
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
|
1718
|
+
'(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
|
1719
|
+
'Accept' => 'application/json, text/javascript, */*; q=0.01',
|
1720
|
+
'Accept-Language' => 'en-US,en;q=0.9',
|
1721
|
+
'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
|
1722
|
+
'X-Requested-With' => 'XMLHttpRequest'
|
1723
|
+
}
|
1724
|
+
|
1725
|
+
retry_count = 0
|
1726
|
+
max_retries = 10
|
1727
|
+
results = []
|
1728
|
+
|
1729
|
+
begin
|
1730
|
+
page = rand(1..15)
|
1731
|
+
url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
|
1732
|
+
puts "Request URL: #{url}"
|
1733
|
+
res = client.get(url)
|
1734
|
+
|
1735
|
+
unless res.status == 200
|
1736
|
+
puts "HTTP Error: #{res.status}"
|
1737
|
+
raise "HTTP Error"
|
1738
|
+
end
|
1735
1739
|
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1740
|
+
json = JSON.parse(res.body)
|
1741
|
+
results = json['results']
|
1742
|
+
mm = []
|
1739
1743
|
|
1740
|
-
|
1741
|
-
|
1742
|
-
|
1743
|
-
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1744
|
+
results.each do |photo|
|
1745
|
+
full_url = photo.dig('urls', 'full').to_s
|
1746
|
+
regular_url = photo.dig('urls', 'regular').to_s
|
1747
|
+
|
1748
|
+
if full_url.start_with?("https://images.unsplash.com/photo-") &&
|
1749
|
+
regular_url.include?("1080")
|
1750
|
+
mm << full_url
|
1751
|
+
end
|
1752
|
+
end
|
1753
|
+
|
1754
|
+
if mm.empty?
|
1755
|
+
raise "No matching image"
|
1756
|
+
end
|
1757
|
+
|
1758
|
+
selected_url = mm.sample
|
1759
|
+
destination_path = "./image/memory.png"
|
1760
|
+
Down.download(selected_url, destination: destination_path)
|
1761
|
+
puts "이미지 다운로드 완료: #{selected_url}"
|
1762
|
+
|
1763
|
+
# 오직 auto_image에서만 자르기 호출
|
1764
|
+
crop_image_height_under_width(destination_path)
|
1765
|
+
|
1766
|
+
rescue => e
|
1767
|
+
retry_count += 1
|
1768
|
+
puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
|
1769
|
+
sleep(3)
|
1770
|
+
if retry_count < max_retries
|
1771
|
+
retry
|
1772
|
+
else
|
1773
|
+
puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
|
1774
|
+
|
1775
|
+
if results && !results.empty?
|
1776
|
+
random_photo = results.sample
|
1777
|
+
fallback_url = random_photo.dig('urls', 'full')
|
1778
|
+
if fallback_url
|
1779
|
+
Down.download(fallback_url, destination: "./image/memory.png")
|
1780
|
+
puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
|
1781
|
+
crop_image_height_under_width("./image/memory.png")
|
1759
1782
|
else
|
1760
|
-
|
1761
|
-
|
1762
|
-
end
|
1783
|
+
puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
|
1784
|
+
color_image
|
1763
1785
|
end
|
1786
|
+
else
|
1787
|
+
puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
|
1788
|
+
color_image
|
1764
1789
|
end
|
1790
|
+
end
|
1791
|
+
end
|
1765
1792
|
end
|
1766
1793
|
|
1794
|
+
|
1767
1795
|
def color_image
|
1768
1796
|
color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
|
1769
1797
|
image = Magick::Image.new(740, 740) { |k| k.background_color = color.sample }
|
@@ -1856,56 +1884,103 @@ class Wordpress
|
|
1856
1884
|
end
|
1857
1885
|
|
1858
1886
|
|
1859
|
-
|
1887
|
+
def image_text(text1, text2)
|
1888
|
+
begin
|
1889
|
+
color = File.open('./color.ini', 'r', encoding: 'utf-8').read.split("\n").map(&:strip).reject(&:empty?)
|
1890
|
+
font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
|
1891
|
+
font2 = './fonts/' + font_files.sample
|
1892
|
+
|
1893
|
+
# 랜덤 글자색 선택
|
1894
|
+
color2 = color.sample
|
1895
|
+
|
1896
|
+
# 헬퍼 함수: 색상 문자열 '#RRGGBB' -> [R,G,B] 배열로 변환
|
1897
|
+
def hex_to_rgb(hex)
|
1898
|
+
hex = hex.delete('#')
|
1899
|
+
[hex[0..1], hex[2..3], hex[4..5]].map { |c| c.to_i(16) }
|
1900
|
+
end
|
1901
|
+
|
1902
|
+
# 헬퍼 함수: 두 RGB 색상의 차이 계산 (간단한 유클리드 거리)
|
1903
|
+
def color_distance(c1, c2)
|
1904
|
+
Math.sqrt(
|
1905
|
+
(c1[0] - c2[0])**2 +
|
1906
|
+
(c1[1] - c2[1])**2 +
|
1907
|
+
(c1[2] - c2[2])**2
|
1908
|
+
)
|
1909
|
+
end
|
1910
|
+
|
1911
|
+
# 대비가 충분히 되는 테두리 색상 선택
|
1912
|
+
max_attempts = 10
|
1913
|
+
stroke_color = nil
|
1914
|
+
base_rgb = hex_to_rgb(color2)
|
1915
|
+
|
1916
|
+
max_attempts.times do
|
1917
|
+
candidate = color.sample
|
1918
|
+
candidate_rgb = hex_to_rgb(candidate)
|
1919
|
+
dist = color_distance(base_rgb, candidate_rgb)
|
1920
|
+
|
1921
|
+
# 거리(차이) 임계값 100 (0~441 범위) — 필요시 조절 가능
|
1922
|
+
if dist > 100
|
1923
|
+
stroke_color = candidate
|
1924
|
+
break
|
1925
|
+
end
|
1926
|
+
end
|
1927
|
+
stroke_color ||= '#000000' # 만약 충분히 다른 색 없으면 검정색 기본값
|
1928
|
+
|
1929
|
+
img = Magick::Image.read('./image/memory.png').first
|
1930
|
+
draw = Magick::Draw.new
|
1931
|
+
|
1932
|
+
raw_message = "#{text1}\n#{text2}".strip
|
1933
|
+
max_width = img.columns * 0.85
|
1934
|
+
max_height = img.rows * 0.6
|
1935
|
+
|
1860
1936
|
begin
|
1861
|
-
|
1862
|
-
font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
|
1863
|
-
font2 = './fonts/' + font_files.sample
|
1864
|
-
color2 = color.sample
|
1865
|
-
|
1866
|
-
img = Magick::Image.read('./image/memory.png').first
|
1867
|
-
draw = Magick::Draw.new
|
1868
|
-
|
1869
|
-
raw_message = "#{text1}\n#{text2}".strip
|
1870
|
-
max_width = img.columns * 0.85
|
1871
|
-
max_height = img.rows * 0.6
|
1872
|
-
|
1873
|
-
begin
|
1874
|
-
size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
|
1875
|
-
rescue
|
1876
|
-
size = 30
|
1877
|
-
end
|
1878
|
-
|
1879
|
-
wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
|
1880
|
-
|
1881
|
-
if @data['이미지설정']['글자그림자'].checked?
|
1882
|
-
img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
|
1883
|
-
draw.gravity = Magick::CenterGravity
|
1884
|
-
draw.pointsize = adjusted_size
|
1885
|
-
draw.fill = '#000000'
|
1886
|
-
draw.font = font2
|
1887
|
-
end
|
1888
|
-
end
|
1889
|
-
|
1890
|
-
draw2 = Magick::Draw.new
|
1891
|
-
img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
|
1892
|
-
draw2.gravity = Magick::CenterGravity
|
1893
|
-
draw2.pointsize = adjusted_size
|
1894
|
-
draw2.fill = color2
|
1895
|
-
draw2.font = font2
|
1896
|
-
if @data['이미지설정']['글자테두리'].checked?
|
1897
|
-
draw2.stroke_width = 2
|
1898
|
-
draw2.stroke = '#000000'
|
1899
|
-
end
|
1900
|
-
end
|
1901
|
-
|
1902
|
-
img.write('./image/memory.png')
|
1937
|
+
size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
|
1903
1938
|
rescue
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1939
|
+
size = 30
|
1940
|
+
end
|
1941
|
+
|
1942
|
+
wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
|
1943
|
+
|
1944
|
+
if @data['이미지설정']['글자그림자'].checked?
|
1945
|
+
img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
|
1946
|
+
draw.gravity = Magick::CenterGravity
|
1947
|
+
draw.pointsize = adjusted_size
|
1948
|
+
draw.fill = '#000000'
|
1949
|
+
draw.font = font2
|
1950
|
+
end
|
1951
|
+
end
|
1952
|
+
|
1953
|
+
if @data['이미지설정']['글자테두리'].checked?
|
1954
|
+
draw_stroke = Magick::Draw.new
|
1955
|
+
img.annotate(draw_stroke, 0, 0, 0, 0, wrapped_message) do
|
1956
|
+
draw_stroke.gravity = Magick::CenterGravity
|
1957
|
+
draw_stroke.pointsize = adjusted_size
|
1958
|
+
draw_stroke.fill = 'none'
|
1959
|
+
draw_stroke.stroke = stroke_color
|
1960
|
+
draw_stroke.stroke_width = rand(5..10)
|
1961
|
+
draw_stroke.font = font2
|
1962
|
+
end
|
1963
|
+
end
|
1964
|
+
|
1965
|
+
draw2 = Magick::Draw.new
|
1966
|
+
img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
|
1967
|
+
draw2.gravity = Magick::CenterGravity
|
1968
|
+
draw2.pointsize = adjusted_size
|
1969
|
+
draw2.fill = color2
|
1970
|
+
draw2.stroke = 'none'
|
1971
|
+
draw2.font = font2
|
1907
1972
|
end
|
1973
|
+
|
1974
|
+
img.write('./image/memory.png')
|
1975
|
+
|
1976
|
+
rescue => e
|
1977
|
+
puts "이미지 폰트 불러오기 오류 재시도... (#{e.message})"
|
1978
|
+
sleep(3)
|
1979
|
+
retry
|
1908
1980
|
end
|
1981
|
+
end
|
1982
|
+
|
1983
|
+
|
1909
1984
|
|
1910
1985
|
def border()
|
1911
1986
|
color = File.open('./color.ini', 'r',:encoding => 'utf-8').read().split("\n")
|
@@ -1932,7 +2007,7 @@ class Wordpress
|
|
1932
2007
|
else
|
1933
2008
|
auto_image()
|
1934
2009
|
end
|
1935
|
-
|
2010
|
+
|
1936
2011
|
# '원본'을 포함한 이미지 크기 옵션 추가
|
1937
2012
|
image_size = [480, 740, 650, 550, 480, 'original']
|
1938
2013
|
size = 0
|
@@ -1956,6 +2031,7 @@ class Wordpress
|
|
1956
2031
|
|
1957
2032
|
change_image_size(size) # 크기 변경 함수 호출
|
1958
2033
|
|
2034
|
+
|
1959
2035
|
if @data['이미지설정']['필터사용'].checked?
|
1960
2036
|
image_filter()
|
1961
2037
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tblog_zon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.53
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zon
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
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
|