// 5 START: Action — Generate Folder Images (overwrite) with GD/TTF, auto-detect size, text = Post Name “{Folder} Media”, refresh thumbnails function gmm_temp_action_generate_folder_images() { if (!current_user_can('manage_options')) { return 'Not allowed.'; } check_admin_referer('gmm_temp_gen_folder_images'); if (!extension_loaded('gd')) { return 'PHP GD extension is not available. Please enable GD or ask hosting support.'; } $root = get_option(GMM_TEMP_OPT_ROOT, ''); $real = $root ? realpath($root) : false; if (!$real || !is_dir($real)) { return 'Root path is not valid. Set it and save first.'; } $real = wp_normalize_path($real); // --- Detect target size (featured > large > fallback) --- $W = 0; $H = 0; if (isset($GLOBALS['_wp_additional_image_sizes']['post-thumbnail'])) { $sz = $GLOBALS['_wp_additional_image_sizes']['post-thumbnail']; $W = !empty($sz['width']) ? (int)$sz['width'] : 0; $H = !empty($sz['height']) ? (int)$sz['height'] : 0; } if ($W <= 0 || $H <= 0) { $W = (int) get_option('large_size_w', 0); $H = (int) get_option('large_size_h', 0); } if ($W <= 0 || $H <= 0) { $W = 1200; $H = 630; } // last resort // --- Find a TTF font (fallback to bitmap if none) --- $font_candidates = [ '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', '/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf', '/usr/share/fonts/truetype/freefont/FreeSansBold.ttf', '/Library/Fonts/Arial Bold.ttf', '/System/Library/Fonts/Supplemental/Arial Bold.ttf', 'C:\\Windows\\Fonts\\arialbd.ttf', ]; $FONT = ''; foreach ($font_candidates as $f) { if (is_file($f)) { $FONT = $f; break; } } $has_ttf = $FONT && function_exists('imagettfbbox') && function_exists('imagettftext'); // Helpers $draw_gradient = function(&$im, $w, $h, $hexTop, $hexBot) { $hex_to_rgb = function($hex){ $hex = ltrim($hex, '#'); return [hexdec(substr($hex,0,2)),hexdec(substr($hex,2,2)),hexdec(substr($hex,4,2))]; }; list($r1,$g1,$b1) = $hex_to_rgb($hexTop); list($r2,$g2,$b2) = $hex_to_rgb($hexBot); for ($y=0; $y<$h; $y++) { $t = $h>1 ? $y/($h-1) : 0; $r = (int) round($r1 + ($r2-$r1)*$t); $g = (int) round($g1 + ($g2-$g1)*$t); $b = (int) round($b1 + ($b2-$b1)*$t); $col = imagecolorallocate($im, $r, $g, $b); imageline($im, 0, $y, $w, $y, $col); } imagefilledrectangle($im, 0, (int)($h*0.72), $w, $h, imagecolorallocatealpha($im, 0,0,0,100)); }; $fit_text = function($title, $w, $h, $fontPath) { $padX = (int) round($w * 0.08); $padY = (int) round($h * 0.08); $boxW = $w - 2*$padX; $boxH = $h - 2*$padY; $measure = function($size, $txt) use ($fontPath) { $bb = imagettfbbox($size, 0, $fontPath, $txt); $width = abs($bb[2]-$bb[0]); $height = abs($bb[7]-$bb[1]); return [$width, $height]; }; $text = trim($title); $lines = [$text]; $maxSize = (int) max(18, min($boxH * 0.45, $boxW * 0.20)); $minSize = 14; $bestSize = $minSize; for ($s=$maxSize; $s>=$minSize; $s-=2) { list($tw,$th) = $measure($s, $text); if ($tw <= $boxW && $th <= $boxH*0.6) { $bestSize=$s; break; } } list($tw,$th) = $measure($bestSize, $text); if ($tw > $boxW && strpos($text,' ') !== false) { $parts = preg_split('~\s+~', $text); $N = count($parts); $mid = (int) floor($N/2); $candidates = []; for ($i=max(1,$mid-2); $i<=min($N-1,$mid+2); $i++) { $candidates[] = [implode(' ', array_slice($parts,0,$i)), implode(' ', array_slice($parts,$i))]; } $best = $candidates[0]; $bestDiff = PHP_INT_MAX; foreach ($candidates as $cand) { $d = abs(strlen($cand[0]) - strlen($cand[1])); if ($d < $bestDiff) { $bestDiff=$d; $best=$cand; } } $lines = [$best[0], $best[1]]; $maxSize2 = (int) max(18, min($boxH * 0.60, $boxW * 0.22)); $bestSize = $minSize; for ($s=$maxSize2; $s>=$minSize; $s-=2) { list($w1,$h1) = $measure($s, $lines[0]); list($w2,$h2) = $measure($s, $lines[1]); $totalH = $h1 + (int)($s*0.35) + $h2; if (max($w1,$w2) <= $boxW && $totalH <= $boxH) { $bestSize=$s; break; } } } return [$lines, $bestSize]; }; $created = 0; $refreshed = 0; $thumbs_set = 0; $errors = 0; $list = @scandir($real); if (!is_array($list)) { return 'Unable to read the root folder.'; } foreach ($list as $base) { if ($base === '.' || $base === '..' || $base[0] === '.') { continue; } $abs = wp_normalize_path($real.'/'.$base); if (!is_dir($abs)) { continue; } $slug = sanitize_title($base); $folder_title = ucwords(trim(preg_replace('~[_\-]+~', ' ', pathinfo($base, PATHINFO_FILENAME)))); $post_title = $folder_title . ' Media'; // <- use Post Name text $target_jpg = $abs.'/'.$slug.'.jpg'; // always (re)write .jpg // --- (Re)generate image file (overwrite) --- $im = imagecreatetruecolor($W, $H); if (!$im) { $errors++; continue; } // Gradient per folder (stable, varied) $seed = crc32($slug); $hue = $seed % 360; $toRgb = function($h,$s,$l){ $c = (1 - abs(2*$l - 1)) * $s; $x = $c * (1 - abs(fmod($h/60,2) - 1)); $m = $l - $c/2; switch (true) { case $h<60: list($r,$g,$b)=[$c,$x,0]; break; case $h<120: list($r,$g,$b)=[$x,$c,0]; break; case $h<180: list($r,$g,$b)=[0,$c,$x]; break; case $h<240: list($r,$g,$b)=[0,$x,$c]; break; case $h<300: list($r,$g,$b)=[$x,0,$c]; break; default: list($r,$g,$b)=[$c,0,$x]; break; } return [ (int)(($r+$m)*255), (int)(($g+$m)*255), (int)(($b+$m)*255) ]; }; list($r1,$g1,$b1) = $toRgb($hue, 0.55, 0.35); list($r2,$g2,$b2) = $toRgb(($hue+20)%360, 0.55, 0.55); $hexTop = sprintf('#%02x%02x%02x',$r1,$g1,$b1); $hexBot = sprintf('#%02x%02x%02x',$r2,$g2,$b2); $draw_gradient($im, $W, $H, $hexTop, $hexBot); if ($has_ttf) { list($lines, $size) = $fit_text($post_title, $W, $H, $FONT); $shadow = imagecolorallocatealpha($im, 0,0,0,60); $white = imagecolorallocate($im, 255,255,255); $measure = function($s,$t) use ($FONT) { $bb=imagettfbbox($s,0,$FONT,$t); return [abs($bb[2]-$bb[0]), abs($bb[7]-$bb[1])]; }; $gap = (int) ($size * 0.35); $heights = []; $widths = []; foreach ($lines as $ln) { list($w1,$h1) = $measure($size,$ln); $widths[]=$w1; $heights[]=$h1; } $totalH = array_sum($heights) + $gap * (count($lines)-1); $xCenter = (int) ($W / 2); $y = (int) (($H - $totalH) / 2); foreach ($lines as $idx => $ln) { list($wLine,$hLine) = $measure($size,$ln); $x = $xCenter - (int)($wLine/2); $y += $hLine; imagettftext($im, $size, 0, $x+2, $y+2, $shadow, $FONT, $ln); imagettftext($im, $size, 0, $x, $y, $white, $FONT, $ln); $y += $gap; } } else { // Bitmap fallback with contrast bar $barH = (int) max(24, $H * 0.18); $barY = (int) (($H - $barH) / 2); $bar = imagecolorallocatealpha($im, 0,0,0,80); imagefilledrectangle($im, 0, $barY, $W, $barY+$barH, $bar); $white = imagecolorallocate($im,255,255,255); $font = 5; $fw = imagefontwidth($font); $fh = imagefontheight($font); $tw = $fw * strlen($post_title); $x = max(6, (int)(($W - $tw) / 2)); $y = (int)(($H - $fh) / 2); imagestring($im, $font, $x, $y, $post_title, $white); } if (!@imagejpeg($im, $target_jpg, 88)) { $errors++; imagedestroy($im); continue; } @chmod($target_jpg, 0644); imagedestroy($im); $created++; // --- Refresh Media Library attachment & featured image --- // Find a post for this folder (if any) $meta_path = trailingslashit($abs); $existing_post = get_posts([ 'post_type' => 'post', 'post_status' => 'any', 'meta_key' => 'gmm_path', 'meta_value' => $meta_path, 'fields' => 'ids', 'posts_per_page' => 1, 'no_found_rows' => true, 'suppress_filters' => true, ]); if (!empty($existing_post)) { $post_id = (int)$existing_post[0]; // If we already have an attachment for this source abs, update its file in uploads; else import new $reuse = function_exists('gmm_temp_find_attachment_by_source_abs') ? gmm_temp_find_attachment_by_source_abs($target_jpg) : 0; if ($reuse) { $dest = get_attached_file($reuse); if ($dest && @copy($target_jpg, $dest)) { if (function_exists('wp_update_image_subsizes')) { @wp_update_image_subsizes($reuse); } else { $meta = @wp_generate_attachment_metadata($reuse, $dest); if ($meta) { @wp_update_attachment_metadata($reuse, $meta); } } set_post_thumbnail($post_id, $reuse); $thumbs_set++; } else { // fallback: re-import if (function_exists('gmm_temp_attach_local_image')) { $att_id = gmm_temp_attach_local_image($post_id, $target_jpg, $post_title); if ($att_id) { $thumbs_set++; } } } } else { if (function_exists('gmm_temp_attach_local_image')) { $att_id = gmm_temp_attach_local_image($post_id, $target_jpg, $post_title); if ($att_id) { $thumbs_set++; } } } $refreshed++; } } $msg = 'Folder Images: regenerated '.$created; $msg .= ', refreshed posts '.$refreshed; $msg .= ', set thumbnails '.$thumbs_set; $msg .= $errors ? ', errors '.$errors : ''; $msg .= '. Generated at '.$W.'×'.$H.( $has_ttf ? ' using TTF anti-aliased text.' : ' (fallback bitmap text).' ).''; return $msg; } // 5 STOP: Action — Generate Folder Images (overwrite) with GD/TTF, auto-detect size, text = Post Name “{Folder} Media”, refresh thumbnails Forum – Virtual Humans – Gameznet Creators Hub
Profile Photo

Virtual Humans

  • Public Group
  • 11 months, 2 weeks ago
  • 0

    Posts

  • 2

    Members

Outfit Changer

This topic contains 0 voices and has 0 replies.
0 voices
0 replies
  • Author
    Posts
  • #100040160
    Andrew

      GOD Tier

      Have you tried ai Outfit Changer?  share your thoughts, questions, hints and tips with the community about this fun ai tool for changing clothes on your photos and avatars.

    You must be logged in to reply to this topic.

    Description

    A Group dedicated to Virtual Humans!
    Whether it’s your own virtual self, an ai chatbot for your website, deepfakes or ai Influencers, here you can discuss and share all aspects from creating avatars to completely fictitious virtual people or ai versions of yourself.